SlideShare une entreprise Scribd logo
1  sur  50
Télécharger pour lire hors ligne
The Top 30
LotusScript
Development Tips

Bill Buchan
HADSL
       © 2006 Wellesley Information Services. All rights reserved.
What We’ll Cover …

•   Introduction
•   Nursery Slopes
•   Everyday Tips
•   Advanced Tips
•   Wrap-up




                     2
Introduction
•   What is this about?
      This talk aims to run through 30 different LotusScript tips
         10 of these tips (Nursery Slopes) are fundamental
         10 of these tips (Everyday Tips) are less well known
         10 of these tips (Advanced Tips) are there to
         provoke thought




                                                                    3
Introduction (cont.)

•   Why 30 tips?
      “The Lazy Programmer” methodology
      Experience and understanding
      Push your comfort zone and provoke thought
•   Who am I?
      Bill Buchan
      Dual PCLP in v3, v4, v5, v6, v7
      10+ years senior development consultancy for
      Enterprise customers
          Learn from my pain!
      5+ years code auditing
      CEO – HADSL – developing best-practice tools
                                                     4
What We’ll Cover …

•   Introduction
•   Nursery Slopes
•   Everyday Tips
•   Advanced Tips
•   Wrap-up




                     5
NS #1: Option Declare
•   You should always use “Option Declare”
•   Yes, but why?
      If not, all variables are created at runtime as variants
          This makes type-checking redundant
          Data conversion costs 10x performance!
          And means all errors will be runtime errors
      Remember: Test lots, test early
      Use the strengths of the compiler to help you




                                                                 6
NS #2: Templates and Versions

•   In terms of custom code, you should always
      Create templates with new code
         Databases with “ntf” extension
         Or databases with Master Template Name set
      Create a separate copy for each version
      Keep them in a central repository
•   Why?
      It makes it far easier to roll back
      Version control
      Easier to construct test cases with “other” versions



                                                             7
NS #3: Application Lifecycle
•   You should always:
      Develop in a development “sandbox”
      Test in a user acceptance environment
      Pass the template to your administrator to apply
•   Why?
      It’s a basic change control system
      Professionalism
      It shakes out “hardcoded” bugs
           Hardcoded server names, paths, replica IDs
      It allows you to run extensive testing without
      affecting production


                                                         8
NS #4: How to Code
  •    How to code?
  •    Code for maintenance
  •    Only code for performance if required
         Get it working before you get it working for speed
  •    Why?
         The highest cost in development is software maintenance
         Make it easier for the person maintaining the application
         It could be YOU

Note



                                                                     9
NS #5: “Measure Twice, Cut Once”
•   Spend more time thinking and less time coding
•   Try to think of at least TWO methods of solving
    a problem
      The best approach is usually a blend of the two
      Think about the data model!
•   Why?
      More planning, less work

“You know it’s been a rough night
                                                        Don't
when you wake up next to some                             Forget

code you don’t recognize”
   - Bob Balaban
                                                                   10
NS #6: Extending Arrays the Easy Way
    Sub initialize()
        Dim myArray() as String
        redim myArray(0)
        call myExtend (myArray, “Hello Sailor”)
    end sub

    function myExtend(S() as String, ns as String) as integer
       if (S(ubound(S)) <> “”) then redim preserve S(ubound(S)+1)
       S(ubound(S)) = ns
       extend = true
    end function


•    Pros:
        No need to keep separate index of array size
        Automatically “trims”
•    Cons:
        Slow with large arrays
        Need to define some “empty” value               GOTCHA!
                                                                    11
NS #7: The List Operator
    Dim WR list as String
    WR(“Peter”) = “Perfect”
    WR(“Penelope”) = “Pitstop”

    Print “Peter’s last name is: “ + WR(“Peter”)
    if not isElement(WR(“Dick”)) then print “Dick isn’t racing!”
    forall thisRacer in WR
       Print listtag(thisracer) + “ “ + thisRacer
    end forall

•    List stores a value with a unique lookup key
        Pros:
           It’s easy and it’s fast
           It’s built right into LotusScript, since v4.5
        Cons:
           You can’t directly read and write a list from
           a document item
                Convert to an array first
                                                               12
NS #8: Logging

•   If you have applications with scheduled Agents
•   Or if you have a diverse range of clients
      Then you need to log your Agent (both client and scheduled)
      runtime status
•   Why?
      Applications will break
      You need to know when they break
      Timing metrics for performance testing
•   Beware!
      Don’t make the logging so
      slow that it affects                GOTCHA!
      application performance!
                                                                    13
NS #9: Code Structure
•   Problem Decomposition:
       Smaller code sequences are easier to:
          Maintain – the majority of the cost
          Reuse – if kept simple
       Rule of thumb: If it’s more than a screenful – can it be
       broken up?
          But – don’t be prescriptive
•   It’s all about
       Problem decomposition
       Maintainability
       Code re-use
       Get the data model right to start with!

                                                                  14
NS #9: Code Structure (cont.)
•   Tips:
      Keep functions/procedures/classes at a manageable size
         But don’t be prescriptive
      Think before decomposing problems
•   Discussion
      “Declare at the top” or “Declare in the code”
         I prefer to declare variables in the code
•   Comments
      Don’t over comment – explain the “Why”!
      I usually only comment non-intuitive algorithms
          “This isn’t what you think … ”
          Comment pseudocode to start with
                                                               15
NS #10: Code Hiding

•   Code hiding
      Means decomposing your code so that consumers don’t
      see your code
           Including yourself
      Infers a logical interface (with clear naming!)
      Customers/peers now write to the “interface”
           Not the code itself
      It simplifies the coding experience
      How?
           “Private/Public” methods in classes, script libraries, etc.



                                                                         16
What We’ll Cover …

•   Introduction
•   Nursery Slopes
•   Everyday Tips
•   Advanced Tips
•   Wrap-up




                     17
ED #1: Error Trapping
•   If I hear “I write perfect code. I don’t need error
    trapping,” I think of two things
       “Yeah, right”
       “Fire this guy”
•   Error handling is mandatory. Seriously.
•   Now, how? Two routes:
       Single error handler at the top, bubble errors up
          Simple, but difficult keeping context
       Error handler implemented at function level
          More work, but much more granular



                                                           18
ED #2: Defensive Coding
•    Defensive coding is:
        Assume the worst, check all input
            On every function
        Does this affect performance? Not usually
        A typical function looks like:

    Function mytest(p1 as String, p2 as String) as
    integer
       mytest = false
       if p1=”” then exit function
       if p2=”” then exit function
       ...
       ' Now actually do something!
       ....
       mytest = true
    end function

                                                     19
ED #3: Protecting Code
•   Commercial applications need to hide their code. How?
      Create a template and “hide design”
         Pro: Easy
         Con: You may allow form customization, etc.
      Or remove LotusScript source code from script libraries
         Use NotesNoteCollection to find script design document
         Replace item “$ScriptLib” with a String – “Hello”
             Con: Not so simple
             Pro: Other design elements can be modified
         Don’t do this on your development copy …



                                                                  20
ED #4: Use NotesDateTime Instead of Strings!

•   Don’t store date/time values as Strings
•   Use NotesDateTime structures, and save them
•   Why?
      You don’t know how the client will interpret dates …
          Is it dd/mm/yyyy or mm/dd/yyyy?
      It means that views will be able to sort on dates
•   This happens more often than you think!




                                                             21
ED #5: DXL as Transport

•   Consider the situation where your customer wants to
    send back “log” documents easily
      Use a LotusScript Agent to:
          Pick up all selected documents                   Solution
          Create a Memo with a Rich Text Field
          Use DXL to store the documents in the RT field
      At the receiving end:
          Unpack the mail message to a DXL Stream
          Construct new documents to store the data
      This is data transfer without replication



                                                                      22
ED #5: DXL as Transport Example Code – Send
 Dim   sSession As New NotesSession
 Dim   dbThis As notesDatabase
 Set   dbThis = sSession.CurrentDatabase
 Dim   dc As NotesDocumentCollection
 Set   dc = dbThis.UnprocessedDocuments

 If (dc Is Nothing) Then exit sub
 If (dc.count < 1) Then exit sub

 Dim doc As NotesDocument
 Set doc = dc.GetFirstDocument

 While (Not doc Is Nothing)

       Dim de As NotesDXLExporter
       Set de = sSession.CreateDXLExporter()
       Call de.setInput(doc)

       Dim dxl As String
       dxl = de.Export
       ' continued overleaf..                  Actual Work


                                                             23
ED #5: DXL as Transport Example Code – Send (cont.)
    Dim dbMail As New NotesDatabase("", "")
    Call dbMail.OpenMail()

    Dim docM As NotesDocument
    Set docM = dbMail.CreateDocument

    Call docM.ReplaceItemValue("Form", "Memo")
    Call docM.ReplaceItemValue("Recipients", "logs@hadsl.com")
    Call docM.ReplaceItemValue("SendTo", "logs@hadsl.com")

    Call docM.ReplaceItemValue("Subject", "Log Documents”)

    Dim rt As New NotesRichTextItem(docM, "Body")
    Call rt.AppendText(dxl)

    Call docM.Send(False)

    Set docM = Nothing
    Set de = Nothing

    Set doc = dc.GetNextDocument(doc)
 Wend

                                                             24
ED #6: Wizards
•   A Wizard interface in Notes Client:
      Create a form with a tabbed table
      Set the tabs to “1”, “2”, “3”, etc.
      Select “Switch Rows Programmatically”
      Set the “name” field to the name of the table
         e.g., “RequestTable”
      Create a variable on the form with $Name
         e.g., “$RequestTable”
      Have “forward” and “back” buttons increment/decrement
      the variable



                                                              25
ED #7: Consuming Web Services
•   Two approaches
      Quick and dirty
         Install MS Soap on client machines
         Write LotusScript to create an MS Soap Object
             Pro: Very quick, handy for testing
             Con: Platform specific, requires DLL             Client
                                                              Issue
             on clients, no timeout
Dim Client As Variant
Set Client = CreateObject("MSSOAP.SoapClient")

'Initialize connection to the Web Service
Call Client.mssoapinit ("http://localhost/testWS.nsf/Simple?wsdl")

'Call our simple GetEmailAddress function provided by Web service
Dim result As String
result = Client.getJoke()

'output result to message box
Messagebox result, 48, "Get Joke"                                   26
ED #7: Consuming Web Services (cont.)
•   Second Approach
      Big and robust
         Create a Java Agent that you pass a Notes document to –
         with all your setup information
         Read the document in your Java Agent, and consume
         the Web service
         Write the results back to your Notes document
         Once the Java Agent returns, read the document for
         the results
      Pro:
         Multi-platform, scalable
      Con
         Quite a lot of work
                                                                   27
ED #8: Classes

•   What are Classes?
      Classes help to:
         Bundle data and code in one place
         Decompose problems into “objects”
         Write smaller, more focused code
         Define and implement the internal data model
      Classes aid reusability
      Pros: Good design methodology, leads to Java
      Cons: “Different,” and takes time to sink in




                                                        28
ED #8: Classes (cont.)

Class Person
    private nName as NotesName
    private strUNID as String

   sub new(strNewName as string, strNewUNID asString)
       me.nnName = new NotesName(strNewName)
       me.strUNID = strNewUNID
   end sub

   public function getName as String
      if (me.nnName is nothing) then exit function
      getName = nnName.Canonical
   end function

   public function getUNID as String
        getUNID = strUNID
   end function
end class
                                                        29
ED #9: Evaluate

•   Evaluate allows you to run @Functions within
    LotusScript
•   Sometimes faster, easier
•   Example:
           evaluate(|@unique|)
•   DON’T:
      Overuse it. Lots of LotusScript functions mimic @functions.
         “strRight” == @StrRight




                                                                    30
ED #10: “Trusted Servers”

•   Scheduled Agents cannot normally open databases on
    other servers
      “Trusted Servers” field in R6 server document, security
      section, allows servers to “trust” other servers
      This allows you to centralize “collection” Agents
      Caveat: Don’t trust servers in another domain!
•   Pros:
      Simplifies architecture
      Fewer Agents
•   Con:
      Relies on fast, reliable network infrastructure …

                                                                31
What We’ll Cover …

•   Introduction
•   Nursery Slopes
•   Everyday Tips
•   Advanced Tips
•   Wrap-up




                     32
Advanced #1: Understanding Binding

•   There are two types of binding
      Early: Set by the compiler
         Pros: Type checking, speed, and ease of use
         Example: “Dim S as String”
      Late: Set at runtime
         Pros: Flexibility, NO type checking
         Cons: Performance, runtime errors

    Dim V as variant
    Dim S as new NotesSession
    set V = S.CurrentDatabase

    print V.getTitle()


                                                       33
Advanced #2: Coding for Performance
•   Remember – Expensive operations include:
      Opening databases and views
      Documents with lots of fields
•   When collecting data:                                Tip
      Cache views where possible
      Use NotesViewEntry instead of opening documents
•   Example:
      100,000 document database
      7 hours for “open every document in database”
         Not using views
      60 minutes using NotesView and opening documents
      12 minutes for “notesviewEntry”
                                                               34
Advanced #3: Lists and Classes

•   Classes bind complex data and operations
•   List looks these up quickly in memory
       Example – Let’s extend our Person class:
dim People list as Person
dim PeopleByUNID list as Person

Dim P as new Person(“Joe Bloggs/ACME”, “010101010201020”)
....
set People(P.getName) = P
set PeopleByUNID(P.getUNID) = P

if (isElement(People(“Joe Bloggs/ACME”))) then _
    Print “Joe's UNID is: “ + People(“Joe Bloggs/ACME”).getUNID


if (isElement(PeopleByUNID(“010101010201020”))) then _

    Print “UNID '010101010201020' is: “ +   _
    PeopleByUNID(“010101010201020”).getName


                                                                  35
Advanced #4: Class Inheritance

•    Class inheritance allows us to “Extend” classes to
     add functionality

    class StaffPerson as Person
        private strStaffID as String

        sub new(strNewPerson as String, strNewUNID as String)
        end sub

        public function setStaffNumber(newNo as String)
            strStaffID = newNo
        end function

        public function getStaffNumber as String
            getStaffNumber = me.strStaffID
        end function
    end class


                                                                36
Advanced #5: Platform-Specific Code With Classes

                                        Class getMem
Dim s as new NotesSession                 function getMem() as long
Dim mem as variant                           getMem = 0
                                          end function
select case s.platform                    sub printMemory
  case “Windows/32”                          print me.getMem()
     set mem = new getMemW32()            end sub
  case “AIX”                            end class
     set mem = new getMemAIX()
  case else                           Class getMemW32 as getMem
     Print “Platform not supported”     function getMem() as long
     set mem = nothing                     getMem =
end case                              getWindowsMemory()
                                        end function
if (not mem is nothing) then          end class
     call mem.printMemory()
                                      Class getMemAIX as getMem
                                        function getMem() as long
                                           getMem = getAIXMemory()
                                        end function
                                      end class                       37
Advanced #6: Version-Specific Code With Classes


Dim s as new NotesSession
dim vCU as variant                   Class createUser
                                       function createUser(...) as integer
select case s.version                     ....
  case 5                               end function
     set vCU = new createUser()      end class
  case 6
     set vCU = new createUserv6()
  case else
     Print “Version not supported”
    set vCU = nothing                Class createUserv6 as createUser
end case                               function createUser(...) as integer
                                          ....
if (not vCU is nothing) then _         end function
     call vCU.CreateUser(....)       end class


                                                                             38
Advanced #7: LSI_Info()/GetThreadInfo

•   LSI_INFO() gives some runtime information
•   Superceded by GetThreadInfo
      GetThreadInfo(11) gives calling class
      GetThreadInfo(10) gives function name
      and lots more …
•   Why?
      Error trapping: We can track where we came from
      We don’t have to pass lists of parameters to error
      trapping code
      Prevents “cut-n-paste coding” errors ...



                                                           39
Advanced #7: LSI_Info()/GetThreadInfo (cont.)
                                            ' calling code...
                                             ...
                                         ExitFunction:
                                             exit function
                                         errorhandler:
Function RaiseError()                        Call RaiseError()
    Dim thisType As String                   resume exitFunction
    Dim es as String                     end function
    thisType = Typename(Me)

    ' Not a class, use the calling module instead
    If (thisType = "") Then thisType = Getthreadinfo(11)

   es = thisType & "::" & Getthreadinfo(10) & ": "

   If (Err = 0) Then
       es = es + "Manually raised an error"
   Else
        es = es + "Run time error: (" + Trim(Str(Err)) + ") " + _
       Error$ + " at line: "+ Trim(Str(Erl))
   End If

    Print es
end function                                                        40
Advanced #8: Execute
•   Execute runs LotusScript code from a String
    •    Example:
        Dim executeString as String
        executeString = |
           print “Hello world”
           dim s as new NotesSession
           dim db as NotesDatabase
           set db = s.currentDatabase
           print “Current Database name is: “ + db.Title
        |

        execute (executeString)


    •    Why?
            Accomodates version/platform differences at runtime


                                                                  41
Advanced #9: Advanced Logging
•   OpenNtf “OpenLog” solution:
      Simple script library addition to your code
      Provides “called from”, “error”, and “Line number”
      functionality
      Simple to implement
•   Example of our “NSD” system:
      On error trap
      Displays all objects in memory




                                                           42
Advanced #10: Mixing Java and LotusScript

•   Use each language to its strengths
      Java – good for Web services, network I/O, multithreaded
      operations
      LotusScript – traditional Notes development language,
      works in UI
•   How to mix:
      Simple: Call an Agent, passing a Notes document
         Fast. I didn’t say you had to save the document!
         Works both ways
      LS2J
         Call Java from LotusScript
         Example on the next slide ...
                                                                 43
Advanced #10: Mixing Java and LotusScript …
                             // Create a Script Library of type “Java” called xlib
                             // containing the following function:
Option Public                  public class calculator {
Use "xlib"                        public int add(int a, int b) { return a + b; }
                                  public int div(int a, int b) { return a / b; }
Uselsx "*javacon"
                                  public int mul(int a, int b) { return a * b; }
                                  public int sub(int a, int b) { return a - b; }
Sub Initialize                }
    Dim mySession As JavaSession
    Dim myClass As JavaClass
    Dim calculator As JavaObject
    Dim a,b,c As Integer
    Set mySession = New JavaSession()
    Set myClass = mySession.GetClass("calculator")
    Set calculator = myClass.CreateObject()
    a = 10
    b = 5
    c = calculator.mul(a,b)
    MessageBox "a * b = " & c
End Sub

                                                                                     44
What We’ll Cover …

•   Introduction
•   Nursery Slopes
•   Everyday Tips
•   Advanced Tips
•   Wrap-up




                     45
Resources

•   Homework:
      Classes – My OO presentation
         http://www.billbuchan.com/web.nsf/htdocs/
         BBUN6MQECQ.htm
•   Steve McConnell, Code Complete 2 (MS Press, 2004).
      www.amazon.com/gp/product/0735619670
•   Duffbert’s presentation on Java
      http://hostit1.connectria.com/twduff/home.nsf/htdocs/TDUF5VA
      QSY.htm
•   Bob Balaban, Programming Domino 4.6 with Java
    (M&T Books, 1998).
      www.amazon.com/gp/product/1558515836
                                                                 46
Resources (cont.)

•   LS 2004/AD104 – LotusScript Tips & Tricks
      www-10.lotus.com/ldd/sandbox.nsf
•   SearchDomino.com – LotusScript Learning Guide
      http://searchdomino.techtarget.com/originalContent/0,289142,si
      d4_gci1001826,00.html
•   NSFTools – Notes Tips
      www.nsftools.com/tips/NotesTips.htm
•   The Notes FAQ !
      www.keysolutions.com/NotesFAQ/




                                                                   47
Resources (cont.)

•   Brian Benz and Rocky Oliver, Lotus Notes and Domino 6
    Programming Bible (Wiley 2003).
      www.amazon.com/gp/product/0764526111
•   Notes.Net (of course)
      www.notes.net




                                                            48
7 Key Points to Take Home

•   You never stop learning good development techniques
•   Develop your code for maintenance
•   Good architecture is the best starting point
•   Understand the problem area before proposing solutions
•   Spend a little time each day reading blogs, THE VIEW,
    and the support database
      Even though specific articles may not be of immediate interest,
      they may pay off in the future
•   A problem shared/discussed is a problem better defined
•   Have fun and enjoy your work

                                                                        49
Your Turn!




                Questions?

             How to Contact Me:
                Bill Buchan
              Bill@hadsl.com
                                  50

Contenu connexe

Similaire à The View - The top 30 Development tips

Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tipsBill Buchan
 
The View - Lotusscript coding best practices
The View - Lotusscript coding best practicesThe View - Lotusscript coding best practices
The View - Lotusscript coding best practicesBill Buchan
 
Speed geeking-lotusscript
Speed geeking-lotusscriptSpeed geeking-lotusscript
Speed geeking-lotusscriptBill Buchan
 
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...panagenda
 
How have we developed product without bugs
How have we developed product without bugsHow have we developed product without bugs
How have we developed product without bugsSigma Software
 
Database Refactoring
Database RefactoringDatabase Refactoring
Database RefactoringAnton Keks
 
Architecting a Large Software Project - Lessons Learned
Architecting a Large Software Project - Lessons LearnedArchitecting a Large Software Project - Lessons Learned
Architecting a Large Software Project - Lessons LearnedJoão Pedro Martins
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureThomas Jaskula
 
Top Tips Every Notes Developer Needs To Know
Top Tips Every Notes Developer Needs To KnowTop Tips Every Notes Developer Needs To Know
Top Tips Every Notes Developer Needs To KnowKathy Brown
 
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedJoão Pedro Martins
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012cobyst
 
12 Step Guide to Lotuscript
12 Step Guide to Lotuscript12 Step Guide to Lotuscript
12 Step Guide to LotuscriptBill Buchan
 
Lotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsLotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsBill Buchan
 
25 Real Life Tips In Ruby on Rails Development
25 Real Life Tips In Ruby on Rails Development25 Real Life Tips In Ruby on Rails Development
25 Real Life Tips In Ruby on Rails DevelopmentBelighted
 
Don't let your tests slow you down
Don't let your tests slow you downDon't let your tests slow you down
Don't let your tests slow you downDaniel Irvine
 
Reverse engineering
Reverse engineeringReverse engineering
Reverse engineeringSaswat Padhi
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agilityelliando dias
 

Similaire à The View - The top 30 Development tips (20)

Ad505 dev blast
Ad505 dev blastAd505 dev blast
Ad505 dev blast
 
Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tips
 
The View - Lotusscript coding best practices
The View - Lotusscript coding best practicesThe View - Lotusscript coding best practices
The View - Lotusscript coding best practices
 
engage 2014 - JavaBlast
engage 2014 - JavaBlastengage 2014 - JavaBlast
engage 2014 - JavaBlast
 
Speed geeking-lotusscript
Speed geeking-lotusscriptSpeed geeking-lotusscript
Speed geeking-lotusscript
 
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...
Way #5 Don’t end up in a ditch because you weren’t aware of roadblocks in you...
 
How have we developed product without bugs
How have we developed product without bugsHow have we developed product without bugs
How have we developed product without bugs
 
Database Refactoring
Database RefactoringDatabase Refactoring
Database Refactoring
 
Architecting a Large Software Project - Lessons Learned
Architecting a Large Software Project - Lessons LearnedArchitecting a Large Software Project - Lessons Learned
Architecting a Large Software Project - Lessons Learned
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architecture
 
Top Tips Every Notes Developer Needs To Know
Top Tips Every Notes Developer Needs To KnowTop Tips Every Notes Developer Needs To Know
Top Tips Every Notes Developer Needs To Know
 
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
 
12 Step Guide to Lotuscript
12 Step Guide to Lotuscript12 Step Guide to Lotuscript
12 Step Guide to Lotuscript
 
Lotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsLotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 Commandments
 
25 Real Life Tips In Ruby on Rails Development
25 Real Life Tips In Ruby on Rails Development25 Real Life Tips In Ruby on Rails Development
25 Real Life Tips In Ruby on Rails Development
 
Don't let your tests slow you down
Don't let your tests slow you downDon't let your tests slow you down
Don't let your tests slow you down
 
CQRS recepies
CQRS recepiesCQRS recepies
CQRS recepies
 
Reverse engineering
Reverse engineeringReverse engineering
Reverse engineering
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
 

Plus de Bill Buchan

Dummies guide to WISPS
Dummies guide to WISPSDummies guide to WISPS
Dummies guide to WISPSBill Buchan
 
WISP for Dummies
WISP for DummiesWISP for Dummies
WISP for DummiesBill Buchan
 
WISP Worst Practices
WISP Worst PracticesWISP Worst Practices
WISP Worst PracticesBill Buchan
 
Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014Bill Buchan
 
Dev buchan leveraging
Dev buchan leveragingDev buchan leveraging
Dev buchan leveragingBill Buchan
 
Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiBill Buchan
 
Dev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent designDev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent designBill Buchan
 
Entwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscriptEntwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscriptBill Buchan
 
Entwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshopEntwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshopBill Buchan
 
Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101Bill Buchan
 
Reporting on your domino environment v1
Reporting on your domino environment v1Reporting on your domino environment v1
Reporting on your domino environment v1Bill Buchan
 
Everything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus scriptEverything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus scriptBill Buchan
 
Admin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-adAdmin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-adBill Buchan
 
Softsphere 08 web services bootcamp
Softsphere 08 web services bootcampSoftsphere 08 web services bootcamp
Softsphere 08 web services bootcampBill Buchan
 
Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013Bill Buchan
 
Lotusphere 2008 Worst practices
Lotusphere 2008 Worst practicesLotusphere 2008 Worst practices
Lotusphere 2008 Worst practicesBill Buchan
 
Lotusphere 2008 - Jumpstart 206 - Web Services Bootcamp
Lotusphere 2008 - Jumpstart 206 - Web Services BootcampLotusphere 2008 - Jumpstart 206 - Web Services Bootcamp
Lotusphere 2008 - Jumpstart 206 - Web Services BootcampBill Buchan
 
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScript
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScriptLotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScript
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScriptBill Buchan
 

Plus de Bill Buchan (20)

Dummies guide to WISPS
Dummies guide to WISPSDummies guide to WISPS
Dummies guide to WISPS
 
WISP for Dummies
WISP for DummiesWISP for Dummies
WISP for Dummies
 
WISP Worst Practices
WISP Worst PracticesWISP Worst Practices
WISP Worst Practices
 
Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014Marykirk raft race presentation night 2014
Marykirk raft race presentation night 2014
 
Dev buchan leveraging
Dev buchan leveragingDev buchan leveraging
Dev buchan leveraging
 
Dev buchan leveraging the notes c api
Dev buchan leveraging the notes c apiDev buchan leveraging the notes c api
Dev buchan leveraging the notes c api
 
Dev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent designDev buchan everything you need to know about agent design
Dev buchan everything you need to know about agent design
 
Entwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscriptEntwicker camp2007 calling-the-c-api-from-lotusscript
Entwicker camp2007 calling-the-c-api-from-lotusscript
 
Entwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshopEntwicker camp2007 blackberry-workshop
Entwicker camp2007 blackberry-workshop
 
Bp301
Bp301Bp301
Bp301
 
Ad507
Ad507Ad507
Ad507
 
Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101Admin2012 buchan web_services-v101
Admin2012 buchan web_services-v101
 
Reporting on your domino environment v1
Reporting on your domino environment v1Reporting on your domino environment v1
Reporting on your domino environment v1
 
Everything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus scriptEverything you ever wanted to know about lotus script
Everything you ever wanted to know about lotus script
 
Admin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-adAdmin camp 2011-domino-sso-with-ad
Admin camp 2011-domino-sso-with-ad
 
Softsphere 08 web services bootcamp
Softsphere 08 web services bootcampSoftsphere 08 web services bootcamp
Softsphere 08 web services bootcamp
 
Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013Connections Lotusphere Worst Practices 2013
Connections Lotusphere Worst Practices 2013
 
Lotusphere 2008 Worst practices
Lotusphere 2008 Worst practicesLotusphere 2008 Worst practices
Lotusphere 2008 Worst practices
 
Lotusphere 2008 - Jumpstart 206 - Web Services Bootcamp
Lotusphere 2008 - Jumpstart 206 - Web Services BootcampLotusphere 2008 - Jumpstart 206 - Web Services Bootcamp
Lotusphere 2008 - Jumpstart 206 - Web Services Bootcamp
 
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScript
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScriptLotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScript
Lotusphere 2007 BP301 Advanced Object Oriented Programming for LotusScript
 

The View - The top 30 Development tips

  • 1. The Top 30 LotusScript Development Tips Bill Buchan HADSL © 2006 Wellesley Information Services. All rights reserved.
  • 2. What We’ll Cover … • Introduction • Nursery Slopes • Everyday Tips • Advanced Tips • Wrap-up 2
  • 3. Introduction • What is this about? This talk aims to run through 30 different LotusScript tips 10 of these tips (Nursery Slopes) are fundamental 10 of these tips (Everyday Tips) are less well known 10 of these tips (Advanced Tips) are there to provoke thought 3
  • 4. Introduction (cont.) • Why 30 tips? “The Lazy Programmer” methodology Experience and understanding Push your comfort zone and provoke thought • Who am I? Bill Buchan Dual PCLP in v3, v4, v5, v6, v7 10+ years senior development consultancy for Enterprise customers Learn from my pain! 5+ years code auditing CEO – HADSL – developing best-practice tools 4
  • 5. What We’ll Cover … • Introduction • Nursery Slopes • Everyday Tips • Advanced Tips • Wrap-up 5
  • 6. NS #1: Option Declare • You should always use “Option Declare” • Yes, but why? If not, all variables are created at runtime as variants This makes type-checking redundant Data conversion costs 10x performance! And means all errors will be runtime errors Remember: Test lots, test early Use the strengths of the compiler to help you 6
  • 7. NS #2: Templates and Versions • In terms of custom code, you should always Create templates with new code Databases with “ntf” extension Or databases with Master Template Name set Create a separate copy for each version Keep them in a central repository • Why? It makes it far easier to roll back Version control Easier to construct test cases with “other” versions 7
  • 8. NS #3: Application Lifecycle • You should always: Develop in a development “sandbox” Test in a user acceptance environment Pass the template to your administrator to apply • Why? It’s a basic change control system Professionalism It shakes out “hardcoded” bugs Hardcoded server names, paths, replica IDs It allows you to run extensive testing without affecting production 8
  • 9. NS #4: How to Code • How to code? • Code for maintenance • Only code for performance if required Get it working before you get it working for speed • Why? The highest cost in development is software maintenance Make it easier for the person maintaining the application It could be YOU Note 9
  • 10. NS #5: “Measure Twice, Cut Once” • Spend more time thinking and less time coding • Try to think of at least TWO methods of solving a problem The best approach is usually a blend of the two Think about the data model! • Why? More planning, less work “You know it’s been a rough night Don't when you wake up next to some Forget code you don’t recognize” - Bob Balaban 10
  • 11. NS #6: Extending Arrays the Easy Way Sub initialize() Dim myArray() as String redim myArray(0) call myExtend (myArray, “Hello Sailor”) end sub function myExtend(S() as String, ns as String) as integer if (S(ubound(S)) <> “”) then redim preserve S(ubound(S)+1) S(ubound(S)) = ns extend = true end function • Pros: No need to keep separate index of array size Automatically “trims” • Cons: Slow with large arrays Need to define some “empty” value GOTCHA! 11
  • 12. NS #7: The List Operator Dim WR list as String WR(“Peter”) = “Perfect” WR(“Penelope”) = “Pitstop” Print “Peter’s last name is: “ + WR(“Peter”) if not isElement(WR(“Dick”)) then print “Dick isn’t racing!” forall thisRacer in WR Print listtag(thisracer) + “ “ + thisRacer end forall • List stores a value with a unique lookup key Pros: It’s easy and it’s fast It’s built right into LotusScript, since v4.5 Cons: You can’t directly read and write a list from a document item Convert to an array first 12
  • 13. NS #8: Logging • If you have applications with scheduled Agents • Or if you have a diverse range of clients Then you need to log your Agent (both client and scheduled) runtime status • Why? Applications will break You need to know when they break Timing metrics for performance testing • Beware! Don’t make the logging so slow that it affects GOTCHA! application performance! 13
  • 14. NS #9: Code Structure • Problem Decomposition: Smaller code sequences are easier to: Maintain – the majority of the cost Reuse – if kept simple Rule of thumb: If it’s more than a screenful – can it be broken up? But – don’t be prescriptive • It’s all about Problem decomposition Maintainability Code re-use Get the data model right to start with! 14
  • 15. NS #9: Code Structure (cont.) • Tips: Keep functions/procedures/classes at a manageable size But don’t be prescriptive Think before decomposing problems • Discussion “Declare at the top” or “Declare in the code” I prefer to declare variables in the code • Comments Don’t over comment – explain the “Why”! I usually only comment non-intuitive algorithms “This isn’t what you think … ” Comment pseudocode to start with 15
  • 16. NS #10: Code Hiding • Code hiding Means decomposing your code so that consumers don’t see your code Including yourself Infers a logical interface (with clear naming!) Customers/peers now write to the “interface” Not the code itself It simplifies the coding experience How? “Private/Public” methods in classes, script libraries, etc. 16
  • 17. What We’ll Cover … • Introduction • Nursery Slopes • Everyday Tips • Advanced Tips • Wrap-up 17
  • 18. ED #1: Error Trapping • If I hear “I write perfect code. I don’t need error trapping,” I think of two things “Yeah, right” “Fire this guy” • Error handling is mandatory. Seriously. • Now, how? Two routes: Single error handler at the top, bubble errors up Simple, but difficult keeping context Error handler implemented at function level More work, but much more granular 18
  • 19. ED #2: Defensive Coding • Defensive coding is: Assume the worst, check all input On every function Does this affect performance? Not usually A typical function looks like: Function mytest(p1 as String, p2 as String) as integer mytest = false if p1=”” then exit function if p2=”” then exit function ... ' Now actually do something! .... mytest = true end function 19
  • 20. ED #3: Protecting Code • Commercial applications need to hide their code. How? Create a template and “hide design” Pro: Easy Con: You may allow form customization, etc. Or remove LotusScript source code from script libraries Use NotesNoteCollection to find script design document Replace item “$ScriptLib” with a String – “Hello” Con: Not so simple Pro: Other design elements can be modified Don’t do this on your development copy … 20
  • 21. ED #4: Use NotesDateTime Instead of Strings! • Don’t store date/time values as Strings • Use NotesDateTime structures, and save them • Why? You don’t know how the client will interpret dates … Is it dd/mm/yyyy or mm/dd/yyyy? It means that views will be able to sort on dates • This happens more often than you think! 21
  • 22. ED #5: DXL as Transport • Consider the situation where your customer wants to send back “log” documents easily Use a LotusScript Agent to: Pick up all selected documents Solution Create a Memo with a Rich Text Field Use DXL to store the documents in the RT field At the receiving end: Unpack the mail message to a DXL Stream Construct new documents to store the data This is data transfer without replication 22
  • 23. ED #5: DXL as Transport Example Code – Send Dim sSession As New NotesSession Dim dbThis As notesDatabase Set dbThis = sSession.CurrentDatabase Dim dc As NotesDocumentCollection Set dc = dbThis.UnprocessedDocuments If (dc Is Nothing) Then exit sub If (dc.count < 1) Then exit sub Dim doc As NotesDocument Set doc = dc.GetFirstDocument While (Not doc Is Nothing) Dim de As NotesDXLExporter Set de = sSession.CreateDXLExporter() Call de.setInput(doc) Dim dxl As String dxl = de.Export ' continued overleaf.. Actual Work 23
  • 24. ED #5: DXL as Transport Example Code – Send (cont.) Dim dbMail As New NotesDatabase("", "") Call dbMail.OpenMail() Dim docM As NotesDocument Set docM = dbMail.CreateDocument Call docM.ReplaceItemValue("Form", "Memo") Call docM.ReplaceItemValue("Recipients", "logs@hadsl.com") Call docM.ReplaceItemValue("SendTo", "logs@hadsl.com") Call docM.ReplaceItemValue("Subject", "Log Documents”) Dim rt As New NotesRichTextItem(docM, "Body") Call rt.AppendText(dxl) Call docM.Send(False) Set docM = Nothing Set de = Nothing Set doc = dc.GetNextDocument(doc) Wend 24
  • 25. ED #6: Wizards • A Wizard interface in Notes Client: Create a form with a tabbed table Set the tabs to “1”, “2”, “3”, etc. Select “Switch Rows Programmatically” Set the “name” field to the name of the table e.g., “RequestTable” Create a variable on the form with $Name e.g., “$RequestTable” Have “forward” and “back” buttons increment/decrement the variable 25
  • 26. ED #7: Consuming Web Services • Two approaches Quick and dirty Install MS Soap on client machines Write LotusScript to create an MS Soap Object Pro: Very quick, handy for testing Con: Platform specific, requires DLL Client Issue on clients, no timeout Dim Client As Variant Set Client = CreateObject("MSSOAP.SoapClient") 'Initialize connection to the Web Service Call Client.mssoapinit ("http://localhost/testWS.nsf/Simple?wsdl") 'Call our simple GetEmailAddress function provided by Web service Dim result As String result = Client.getJoke() 'output result to message box Messagebox result, 48, "Get Joke" 26
  • 27. ED #7: Consuming Web Services (cont.) • Second Approach Big and robust Create a Java Agent that you pass a Notes document to – with all your setup information Read the document in your Java Agent, and consume the Web service Write the results back to your Notes document Once the Java Agent returns, read the document for the results Pro: Multi-platform, scalable Con Quite a lot of work 27
  • 28. ED #8: Classes • What are Classes? Classes help to: Bundle data and code in one place Decompose problems into “objects” Write smaller, more focused code Define and implement the internal data model Classes aid reusability Pros: Good design methodology, leads to Java Cons: “Different,” and takes time to sink in 28
  • 29. ED #8: Classes (cont.) Class Person private nName as NotesName private strUNID as String sub new(strNewName as string, strNewUNID asString) me.nnName = new NotesName(strNewName) me.strUNID = strNewUNID end sub public function getName as String if (me.nnName is nothing) then exit function getName = nnName.Canonical end function public function getUNID as String getUNID = strUNID end function end class 29
  • 30. ED #9: Evaluate • Evaluate allows you to run @Functions within LotusScript • Sometimes faster, easier • Example: evaluate(|@unique|) • DON’T: Overuse it. Lots of LotusScript functions mimic @functions. “strRight” == @StrRight 30
  • 31. ED #10: “Trusted Servers” • Scheduled Agents cannot normally open databases on other servers “Trusted Servers” field in R6 server document, security section, allows servers to “trust” other servers This allows you to centralize “collection” Agents Caveat: Don’t trust servers in another domain! • Pros: Simplifies architecture Fewer Agents • Con: Relies on fast, reliable network infrastructure … 31
  • 32. What We’ll Cover … • Introduction • Nursery Slopes • Everyday Tips • Advanced Tips • Wrap-up 32
  • 33. Advanced #1: Understanding Binding • There are two types of binding Early: Set by the compiler Pros: Type checking, speed, and ease of use Example: “Dim S as String” Late: Set at runtime Pros: Flexibility, NO type checking Cons: Performance, runtime errors Dim V as variant Dim S as new NotesSession set V = S.CurrentDatabase print V.getTitle() 33
  • 34. Advanced #2: Coding for Performance • Remember – Expensive operations include: Opening databases and views Documents with lots of fields • When collecting data: Tip Cache views where possible Use NotesViewEntry instead of opening documents • Example: 100,000 document database 7 hours for “open every document in database” Not using views 60 minutes using NotesView and opening documents 12 minutes for “notesviewEntry” 34
  • 35. Advanced #3: Lists and Classes • Classes bind complex data and operations • List looks these up quickly in memory Example – Let’s extend our Person class: dim People list as Person dim PeopleByUNID list as Person Dim P as new Person(“Joe Bloggs/ACME”, “010101010201020”) .... set People(P.getName) = P set PeopleByUNID(P.getUNID) = P if (isElement(People(“Joe Bloggs/ACME”))) then _ Print “Joe's UNID is: “ + People(“Joe Bloggs/ACME”).getUNID if (isElement(PeopleByUNID(“010101010201020”))) then _ Print “UNID '010101010201020' is: “ + _ PeopleByUNID(“010101010201020”).getName 35
  • 36. Advanced #4: Class Inheritance • Class inheritance allows us to “Extend” classes to add functionality class StaffPerson as Person private strStaffID as String sub new(strNewPerson as String, strNewUNID as String) end sub public function setStaffNumber(newNo as String) strStaffID = newNo end function public function getStaffNumber as String getStaffNumber = me.strStaffID end function end class 36
  • 37. Advanced #5: Platform-Specific Code With Classes Class getMem Dim s as new NotesSession function getMem() as long Dim mem as variant getMem = 0 end function select case s.platform sub printMemory case “Windows/32” print me.getMem() set mem = new getMemW32() end sub case “AIX” end class set mem = new getMemAIX() case else Class getMemW32 as getMem Print “Platform not supported” function getMem() as long set mem = nothing getMem = end case getWindowsMemory() end function if (not mem is nothing) then end class call mem.printMemory() Class getMemAIX as getMem function getMem() as long getMem = getAIXMemory() end function end class 37
  • 38. Advanced #6: Version-Specific Code With Classes Dim s as new NotesSession dim vCU as variant Class createUser function createUser(...) as integer select case s.version .... case 5 end function set vCU = new createUser() end class case 6 set vCU = new createUserv6() case else Print “Version not supported” set vCU = nothing Class createUserv6 as createUser end case function createUser(...) as integer .... if (not vCU is nothing) then _ end function call vCU.CreateUser(....) end class 38
  • 39. Advanced #7: LSI_Info()/GetThreadInfo • LSI_INFO() gives some runtime information • Superceded by GetThreadInfo GetThreadInfo(11) gives calling class GetThreadInfo(10) gives function name and lots more … • Why? Error trapping: We can track where we came from We don’t have to pass lists of parameters to error trapping code Prevents “cut-n-paste coding” errors ... 39
  • 40. Advanced #7: LSI_Info()/GetThreadInfo (cont.) ' calling code... ... ExitFunction: exit function errorhandler: Function RaiseError() Call RaiseError() Dim thisType As String resume exitFunction Dim es as String end function thisType = Typename(Me) ' Not a class, use the calling module instead If (thisType = "") Then thisType = Getthreadinfo(11) es = thisType & "::" & Getthreadinfo(10) & ": " If (Err = 0) Then es = es + "Manually raised an error" Else es = es + "Run time error: (" + Trim(Str(Err)) + ") " + _ Error$ + " at line: "+ Trim(Str(Erl)) End If Print es end function 40
  • 41. Advanced #8: Execute • Execute runs LotusScript code from a String • Example: Dim executeString as String executeString = | print “Hello world” dim s as new NotesSession dim db as NotesDatabase set db = s.currentDatabase print “Current Database name is: “ + db.Title | execute (executeString) • Why? Accomodates version/platform differences at runtime 41
  • 42. Advanced #9: Advanced Logging • OpenNtf “OpenLog” solution: Simple script library addition to your code Provides “called from”, “error”, and “Line number” functionality Simple to implement • Example of our “NSD” system: On error trap Displays all objects in memory 42
  • 43. Advanced #10: Mixing Java and LotusScript • Use each language to its strengths Java – good for Web services, network I/O, multithreaded operations LotusScript – traditional Notes development language, works in UI • How to mix: Simple: Call an Agent, passing a Notes document Fast. I didn’t say you had to save the document! Works both ways LS2J Call Java from LotusScript Example on the next slide ... 43
  • 44. Advanced #10: Mixing Java and LotusScript … // Create a Script Library of type “Java” called xlib // containing the following function: Option Public public class calculator { Use "xlib" public int add(int a, int b) { return a + b; } public int div(int a, int b) { return a / b; } Uselsx "*javacon" public int mul(int a, int b) { return a * b; } public int sub(int a, int b) { return a - b; } Sub Initialize } Dim mySession As JavaSession Dim myClass As JavaClass Dim calculator As JavaObject Dim a,b,c As Integer Set mySession = New JavaSession() Set myClass = mySession.GetClass("calculator") Set calculator = myClass.CreateObject() a = 10 b = 5 c = calculator.mul(a,b) MessageBox "a * b = " & c End Sub 44
  • 45. What We’ll Cover … • Introduction • Nursery Slopes • Everyday Tips • Advanced Tips • Wrap-up 45
  • 46. Resources • Homework: Classes – My OO presentation http://www.billbuchan.com/web.nsf/htdocs/ BBUN6MQECQ.htm • Steve McConnell, Code Complete 2 (MS Press, 2004). www.amazon.com/gp/product/0735619670 • Duffbert’s presentation on Java http://hostit1.connectria.com/twduff/home.nsf/htdocs/TDUF5VA QSY.htm • Bob Balaban, Programming Domino 4.6 with Java (M&T Books, 1998). www.amazon.com/gp/product/1558515836 46
  • 47. Resources (cont.) • LS 2004/AD104 – LotusScript Tips & Tricks www-10.lotus.com/ldd/sandbox.nsf • SearchDomino.com – LotusScript Learning Guide http://searchdomino.techtarget.com/originalContent/0,289142,si d4_gci1001826,00.html • NSFTools – Notes Tips www.nsftools.com/tips/NotesTips.htm • The Notes FAQ ! www.keysolutions.com/NotesFAQ/ 47
  • 48. Resources (cont.) • Brian Benz and Rocky Oliver, Lotus Notes and Domino 6 Programming Bible (Wiley 2003). www.amazon.com/gp/product/0764526111 • Notes.Net (of course) www.notes.net 48
  • 49. 7 Key Points to Take Home • You never stop learning good development techniques • Develop your code for maintenance • Good architecture is the best starting point • Understand the problem area before proposing solutions • Spend a little time each day reading blogs, THE VIEW, and the support database Even though specific articles may not be of immediate interest, they may pay off in the future • A problem shared/discussed is a problem better defined • Have fun and enjoy your work 49
  • 50. Your Turn! Questions? How to Contact Me: Bill Buchan Bill@hadsl.com 50