SlideShare a Scribd company logo
1 of 57
Download to read offline
30 Proven Tips to
Optimize Your
LotusScript
Development
Bill Buchan
HADSL
          © 2007 Wellesley Information Services. All rights reserved.
What We’ll Cover …
•   Introduction
•   Theory
•   Practice
•   Advanced
•   Wrap-up




                     2
Introduction
•   Who is the target audience?
       Lotus Notes Developers
•   What is this about?
       This talk aims to run through 30 different LotusScript tips
          10 of these tips (“Theory”) are fundamental
          10 of these tips (“Practice”) are what you should be doing
          10 of these tips (“Advanced”) 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 for Enterprise customers
          Learn from my pain!
       5+ years code auditing
       CEO – HADSL – developing best-practice tools


                                                           4
What We’ll Cover …
•   Introduction
•   Theory
•   Practice
•   Advanced
•   Wrap-up




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




                                                                6
Theory #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
Theory #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
Theory #3: Application Lifecycle (cont.)


   Developer           manager             Dev
                        edito
                                r
                        us
                          er               UAT

                            a   ger
                        man
Administrator          manager              Production




                                                    9
Theory #4: “Measure Twice, Cut Once”
•   Spend more time thinking and less time coding
•   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
    when you wake up next to some
    code you don’t recognize.”
       – Bob Balaban



                                                          10
Theory #5: Code Structure
•   Problem decomposition:
       Smaller code sequences are easier to:
          Maintain – the majority of the cost
          Reuse – if kept simple
       Rule of thumb: If its more than a screenful – can it be
        broken up?
          But – don’t be prescriptive

•   It’s all about:
       Problem decomposition
       Maintainability
       Code reuse
       Get the data model right to start with!

                                                                  11
Theory #5: 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




                                                           12
Theory #6: How to Code
•   How to code
       Code for maintenance
          Code updates cost more than new code
       Architect well. Get the data model right to start with.
•   Only code for performance, if required
       Get it working before getting it working for speed
•   Why?
       The highest cost in development is software maintenance
       Make it easier for the person maintaining the app
       It could be YOU




                                                                  13
Theory #7: How to Test
•   Test soon, test often, test completely
       Look at test-driven development
          Write the specification
          Write the structure
          Write the tests
          Write the code
       Automatic testing means:
          Far easier to regression test all the time
       Minimize run-time errors by:
          Always assuming that data operations outside the current
           database may fail
          Trapping all run-time errors and providing an execution
           path that fails safely
                                                           14
Theory #7: How to Test (cont.)
•   Why test early?
       Costs rise as the tests fail further away from development
       Cheapest to most expensive are:
          Unit tests — by the developer
          User acceptance tests (UATs) — by the tester
          End-user failure — by the user
       The more tests you perform in unit testing:
          The cheaper your development will be
          The more professional your colleagues will think you are
          The more your boss will like you




                                                            15
Theory #8: “Attitude”
•   The first rule of Best Practices is:
       There is no Best Practice!
•   Seriously:
       Don’t use Best Practices in a prescriptive manner
       Examine each one and decide whether it makes sense in
        this context
       Be open to new ideas
•   Attitude is better than prescriptive coding
       No “Not invented here” syndrome
       Collaborate
       “The Lazy Programmer”


                                                          16
Theory #9: Comments
 •   Comments
         Don’t over-comment – explain the “Why!”
         I usually only comment non-intuitive algorithms
             “This isn’t what you think … ”
 •   A good use of comments is to write meta-code
         For instance, when first writing a function, write the code-
          branches as a series of comments
         Leave them in once the code is complete

Function test (param1 as String, param2 as String) as integer
   ' check the parameters and bail out if incorrect.
     ' Add Param 1 to param 2
     ' Check it’s valid. If so – update...
   ' Errorhandler
end function
                                                                  17
Theory #9: Comments (cont.)
•   Remember:
       Comments consume code space in LotusScript
       There’s a 64k — about 1,400 line — limit for each code
        sequence
          This should not normally be an issue
          Classes, of course, are all declared in Declarations
          In terms of classes, you can “subclass” to break up large
           class declarations
•   Check out LotusScript.doc:
       www.lsdoc.org
       It’s a “JavaDoc for LotusScript”
       You can annotate code to make the comments clearer


                                                             18
Theory #10: Error Handling
•   An Error is thrown at run-time when:
       A resource is unavailable: Database, server, memory
       File I/O breaks
       Etc., etc.
•   Execution stops at the point of error
•   Sets error information:
       Error$ — a textual description
       Err — a numeric error code
       Erl — the line number of the error
•   Jumps to the error handling routine
       If there is no error handling routine in the current code
        sequence, jumps to calling function
       If top-level function has no error handler, then default error
        handling is used
                                                                19
Theory #10: Error Handling (cont.)
•   If an error occurs in the middle of a critical sequence of
    updates, possibly some updates will happen, and some
    will not
       Serious data consistency errors
       Get all your validation done before committing transactions
       Perform all the transaction “commits” at the same time
          In our case, all the “saves”
       Defensive coding minimizes this effect
       Do not use “on error goto next”
•   You must deal with errors



                                                             20
Theory #10: Error Handling (cont.)
•   Two approaches:
       Error trap in almost every routine
          Very granular, lots of information
          Minimal chance of breaking transactions
          However, lots of code
       Error trap at the top
          Very simple, minimal code
          You will lose context — you might not be able to get valid
           data on how the error happened
          You might break transactions — and therefore compromise
           data integrity
•   I recommend:
       Error trap in most routines!
                                                            21
What We’ll Cover …
•   Introduction
•   Theory
•   Practice
•   Advanced
•   Wrap-up




                     22
Practice #1: The List Operator
Dim Pres list as String
Pres(“George”) = “Bush”
Pres(“Bill”) = “Clinton”

Print “Georges’s last name is: “ + Pres(“George”)
if not isElement(Pres(“Chad”)) then print “Chad wasn’t
found”
forall thisPres in Pres
   Print listtag(thisPres) + “ “ + thisPres
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
                                                              23
Practice #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

                                                     24
Practice #3: 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
                                                           25
Practice #4: 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)
        run-time 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
        application performance!

                                                            26
Practice #4: Logging (cont.)
•   OpenLog is an OpenNTF Project:
        www.openntf.org
•   It provides a framework for collecting error logging
        To use in your database:
           Copy the script libraries from the OpenLog database
           Update the code:

    Function test(param1 as String) as integer
       Test = false
       on error goto errorhandler
       ' ...
       Test = true
    exitFunction:
       exit function
    errorhandler:
       call logError()
       resume exitfunction
    end function
                                                             27
Practice #4: Logging (cont.)
•   Example OpenLog output:




                               28
Practice #5: 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.




                                                                29
Practice #6: 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!
       And things always break on the 13th of the month




                                                             30
Practice #7: 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




                                                         31
Practice #8: Consuming Web Services
 •   Two approaches: First, 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
             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"
                                                            32
Practice #8: Consuming Web Services (cont.)
•   Two approaches: Second, 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




                                                            33
Practice #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




                                                            34
Practice #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 …


                                                             35
What We’ll Cover …
•   Introduction
•   Theory
•   Practice
•   Advanced
•   Wrap-up




                     36
Advanced #1: Custom Classes
•   What are Custom Classes?
       Custom 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
       Custom Classes aid reusability
          Pros: Good design methodology, leads to Java
          Cons: “Different,” and takes time to sink in




                                                          37
Advanced #1: Custom 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


                                                        38
Advanced #2: 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 run-time
          Pros: Flexibility, NO type checking
          Cons: Performance, run-time errors



    Dim V as variant
    Dim S as new NotesSession
    set V = S.CurrentDatabase
    print V.getTitle()


                                                         39
Advanced #2: Understanding Binding (cont.)

Function ListCollection(p as variant) as integer
   test = false
  if (typeName(p) = “NOTESVIEW”) or _
  (typeName(p) = “NOTESDOCUMENTCOLLECTION”) then
     ' decompose this collection into a number of
     ' single document calls to myself
     dim doc as NotesDocument
     set doc = P.getFirstDocument
     while (not doc is nothing)
        call listCollection(doc)
        set doc = p.getNextDocument(doc)
     wend
  else
     ' We've been passed a single document.
     ' Process it.
     Print “I have been passed doc: “ + doc.Title(0)
     test = true
  end if
end function

                                                   40
Advanced #3: Coding for Performance
•   Remember: Expensive operations include:
       Opening databases and views
       Documents with lots of fields
•   When collecting data:
       Cache views where possible
       Use NotesViewEntry instead of opening documents




                                                          41
Advanced #3: Coding for Performance (cont.)
•   Performance 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”




        See also:
        Application Performance Techniques for Notes and Web Clients
        (Jamie Magee)
                                                              42
Advanced #4: Lists and Custom Classes
 •   Custom Classes bind complex data and operations
 •   Lists look 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


                                                            43
Advanced #5: 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




                                                       44
Advanced #6: Encapsulation
•   Encapsulation allows us to include other complex types
    in our classes:
       Allows you to collect different types of
        complex information




class Department
   private headOfDepartment as Person
   private members list as Person as String
   private departmentname as String
   private Locations list as String
   …
end class



                                                   45
Advanced #7: 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()        ….
  case 6                             end class
     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



                                                                 46
Advanced #8: LSI_Info()/GetThreadInfo
•   LSI_INFO() gives some run-time 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 ...




                                                             47
Advanced #8: LSI_Info()/GetThreadInfo (cont.)
                                            ' calling code...
                                             ...
                                         ExitFunction:
                                             exit function
                                         errorhandler:
                                             Call RaiseError()
Function RaiseError()                        resume exitFunction
    Dim thisType As String               end function
    Dim es as String
    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
                                                            48
Advanced #9: 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?
           Accommodates version/platform differences at run-time




                                                           49
Advanced #10: Mixing Java and LotusScript
•   Use each language to its strengths:
       Java – good for Web services, network I/O, multi-threaded
        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 ...




                                                              50
Advanced #10: Mixing Java and LotusScript …
                             // Create a Script Library of type “Java” called xlib
                             // containing the following function:
                              public class calculator {
Option Public                     public int add(int a, int b) { return a + b; }
Use "xlib"                        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

                                                                                 51
What We’ll Cover …
•   Introduction
•   Theory
•   Practice
•   Advanced Tips
•   Wrap-up




                     52
Resources
•   Homework:
       Classes – my OO presentation
          www.billbuchan.com/web.nsf/htdocs/BBUN6MQECQ.htm
       Steve McConnell, “Code Complete, Second
        Edition” (Microsoft Press, 2004)
          www.amazon.com/gp/product/0735619670
       Duffbert’s presentation on Java
          http://hostit1.connectria.com/twduff/home.nsf/htdocs/
           TDUF5VAQSY.htm
       Bob Balaban, “Programming Domino 4.6 with Java” (M&T
        Books, 1998)
          http://www.amazon.com/gp/product/1558515836




                                                          53
Resources (cont.)
•   LS 2004/AD104 – LotusScript Tips & Tricks
       http://www-10.lotus.com/ldd/sandbox.nsf/ecc552f1ab6e46e
        4852568a90055c4cd/68797abc4efa809a85256e51006a2c8a?
        OpenDocument&Highlight=0,AD104
•   nsftools – Notes Tips
       www.nsftools.com/tips/NotesTips.htm
•   The Notes FAQ!
       www.keysolutions.com/NotesFAQ/




                                                          54
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
•   Articles in THE VIEW
       André Guirard, “Speed up view development — A LotusScript
        agent to automatically create a view with fields from any
        form” (THE VIEW, July/August 2006)
       Mikkel Heisterberg, “Self-documenting LotusScript
        code” (THE VIEW, January/February 2006)



                                                          55
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

                                                            56
Your Turn!




             How to contact me:
                Bill Buchan
              Bill@hadsl.com
                                  57

More Related Content

What's hot

Refactoring legacy code driven by tests - ITA
Refactoring legacy code driven by tests -  ITARefactoring legacy code driven by tests -  ITA
Refactoring legacy code driven by tests - ITALuca Minudel
 
Refactor your code: when, why and how?
Refactor your code: when, why and how?Refactor your code: when, why and how?
Refactor your code: when, why and how?Nacho Cougil
 
Refactor your code: when, why and how (revisited)
Refactor your code: when, why and how (revisited)Refactor your code: when, why and how (revisited)
Refactor your code: when, why and how (revisited)Nacho Cougil
 
Tdd practices
Tdd practicesTdd practices
Tdd practicesaxykim00
 
Agile Test Driven Development
Agile Test Driven DevelopmentAgile Test Driven Development
Agile Test Driven DevelopmentViraf Karai
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven DevelopmentLim Chanmann
 
Simplify Your Life with CQRS
Simplify Your Life with CQRSSimplify Your Life with CQRS
Simplify Your Life with CQRSJoel Mason
 
xUnit and TDD: Why and How in Enterprise Software, August 2012
xUnit and TDD: Why and How in Enterprise Software, August 2012xUnit and TDD: Why and How in Enterprise Software, August 2012
xUnit and TDD: Why and How in Enterprise Software, August 2012Justin Gordon
 
Development Environment Tips
Development Environment TipsDevelopment Environment Tips
Development Environment TipsAdam Culp
 
Extreme Programming (XP): Revisted
Extreme Programming (XP): RevistedExtreme Programming (XP): Revisted
Extreme Programming (XP): RevistedMike Harris
 
10 Big Ideas from Industry
10 Big Ideas from Industry10 Big Ideas from Industry
10 Big Ideas from IndustryGarth Gilmour
 
Test driven development vs Behavior driven development
Test driven development vs Behavior driven developmentTest driven development vs Behavior driven development
Test driven development vs Behavior driven developmentGallop Solutions
 
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-Brock
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-BrockPragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-Brock
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-BrockJoseph Yoder
 
Winning strategies in Test Automation
Winning strategies in Test AutomationWinning strategies in Test Automation
Winning strategies in Test AutomationXBOSoft
 

What's hot (20)

Refactoring legacy code driven by tests - ITA
Refactoring legacy code driven by tests -  ITARefactoring legacy code driven by tests -  ITA
Refactoring legacy code driven by tests - ITA
 
Refactor your code: when, why and how?
Refactor your code: when, why and how?Refactor your code: when, why and how?
Refactor your code: when, why and how?
 
Refactor your code: when, why and how (revisited)
Refactor your code: when, why and how (revisited)Refactor your code: when, why and how (revisited)
Refactor your code: when, why and how (revisited)
 
Tdd
TddTdd
Tdd
 
Agile Testing Days
Agile Testing DaysAgile Testing Days
Agile Testing Days
 
Test drive on driven development process
Test drive on driven development processTest drive on driven development process
Test drive on driven development process
 
Tdd practices
Tdd practicesTdd practices
Tdd practices
 
Agile Test Driven Development
Agile Test Driven DevelopmentAgile Test Driven Development
Agile Test Driven Development
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
TDD refresher
TDD refresherTDD refresher
TDD refresher
 
Simplify Your Life with CQRS
Simplify Your Life with CQRSSimplify Your Life with CQRS
Simplify Your Life with CQRS
 
xUnit and TDD: Why and How in Enterprise Software, August 2012
xUnit and TDD: Why and How in Enterprise Software, August 2012xUnit and TDD: Why and How in Enterprise Software, August 2012
xUnit and TDD: Why and How in Enterprise Software, August 2012
 
Tdd
TddTdd
Tdd
 
Development Environment Tips
Development Environment TipsDevelopment Environment Tips
Development Environment Tips
 
TDD with RSpec
TDD with RSpecTDD with RSpec
TDD with RSpec
 
Extreme Programming (XP): Revisted
Extreme Programming (XP): RevistedExtreme Programming (XP): Revisted
Extreme Programming (XP): Revisted
 
10 Big Ideas from Industry
10 Big Ideas from Industry10 Big Ideas from Industry
10 Big Ideas from Industry
 
Test driven development vs Behavior driven development
Test driven development vs Behavior driven developmentTest driven development vs Behavior driven development
Test driven development vs Behavior driven development
 
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-Brock
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-BrockPragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-Brock
Pragmatic Not Dogmatic TDD Agile2012 by Joseph Yoder and Rebecca Wirfs-Brock
 
Winning strategies in Test Automation
Winning strategies in Test AutomationWinning strategies in Test Automation
Winning strategies in Test Automation
 

Similar to The View - 30 proven Lotuscript tips

Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tipsBill Buchan
 
The View - The top 30 Development tips
The View - The top 30 Development tipsThe View - The top 30 Development tips
The View - The top 30 Development tipsBill Buchan
 
Driving application development through behavior driven development
Driving application development through behavior driven developmentDriving application development through behavior driven development
Driving application development through behavior driven developmentEinar Ingebrigtsen
 
The "Evils" of Optimization
The "Evils" of OptimizationThe "Evils" of Optimization
The "Evils" of OptimizationBlackRabbitCoder
 
Performance Optimization of Cloud Based Applications by Peter Smith, ACL
Performance Optimization of Cloud Based Applications by Peter Smith, ACLPerformance Optimization of Cloud Based Applications by Peter Smith, ACL
Performance Optimization of Cloud Based Applications by Peter Smith, ACLTriNimbus
 
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
 
10 Reasons You MUST Consider Pattern-Aware Programming
10 Reasons You MUST Consider Pattern-Aware Programming10 Reasons You MUST Consider Pattern-Aware Programming
10 Reasons You MUST Consider Pattern-Aware ProgrammingPostSharp Technologies
 
Code review guidelines
Code review guidelinesCode review guidelines
Code review guidelinesLalit Kale
 
YAGNI Principle and Clean Code
YAGNI Principle and Clean CodeYAGNI Principle and Clean Code
YAGNI Principle and Clean CodeLuan Reffatti
 
Lotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsLotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsBill Buchan
 
Arch factory - Agile Design: Best Practices
Arch factory - Agile Design: Best PracticesArch factory - Agile Design: Best Practices
Arch factory - Agile Design: Best PracticesIgor Moochnick
 
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
 
Topic production code
Topic production codeTopic production code
Topic production codeKavi Kumar
 
You and your code.pdf
You and your code.pdfYou and your code.pdf
You and your code.pdfTony Khánh
 
Agile Methodologies And Extreme Programming - Svetlin Nakov
Agile Methodologies And Extreme Programming - Svetlin NakovAgile Methodologies And Extreme Programming - Svetlin Nakov
Agile Methodologies And Extreme Programming - Svetlin NakovSvetlin Nakov
 
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
 
Agile Methodologies And Extreme Programming
Agile Methodologies And Extreme ProgrammingAgile Methodologies And Extreme Programming
Agile Methodologies And Extreme ProgrammingUtkarsh Khare
 
Software Quality via Unit Testing
Software Quality via Unit TestingSoftware Quality via Unit Testing
Software Quality via Unit TestingShaun Abram
 

Similar to The View - 30 proven Lotuscript tips (20)

Dev buchan 30 proven tips
Dev buchan 30 proven tipsDev buchan 30 proven tips
Dev buchan 30 proven tips
 
The View - The top 30 Development tips
The View - The top 30 Development tipsThe View - The top 30 Development tips
The View - The top 30 Development tips
 
Driving application development through behavior driven development
Driving application development through behavior driven developmentDriving application development through behavior driven development
Driving application development through behavior driven development
 
The "Evils" of Optimization
The "Evils" of OptimizationThe "Evils" of Optimization
The "Evils" of Optimization
 
Performance Optimization of Cloud Based Applications by Peter Smith, ACL
Performance Optimization of Cloud Based Applications by Peter Smith, ACLPerformance Optimization of Cloud Based Applications by Peter Smith, ACL
Performance Optimization of Cloud Based Applications by Peter Smith, ACL
 
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
 
10 Reasons You MUST Consider Pattern-Aware Programming
10 Reasons You MUST Consider Pattern-Aware Programming10 Reasons You MUST Consider Pattern-Aware Programming
10 Reasons You MUST Consider Pattern-Aware Programming
 
Code review guidelines
Code review guidelinesCode review guidelines
Code review guidelines
 
YAGNI Principle and Clean Code
YAGNI Principle and Clean CodeYAGNI Principle and Clean Code
YAGNI Principle and Clean Code
 
Lotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 CommandmentsLotusphere 2009 The 11 Commandments
Lotusphere 2009 The 11 Commandments
 
It's XP, Stupid
It's XP, StupidIt's XP, Stupid
It's XP, Stupid
 
While You Are Coding
While You Are CodingWhile You Are Coding
While You Are Coding
 
Arch factory - Agile Design: Best Practices
Arch factory - Agile Design: Best PracticesArch factory - Agile Design: Best Practices
Arch factory - Agile Design: Best Practices
 
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
 
Topic production code
Topic production codeTopic production code
Topic production code
 
You and your code.pdf
You and your code.pdfYou and your code.pdf
You and your code.pdf
 
Agile Methodologies And Extreme Programming - Svetlin Nakov
Agile Methodologies And Extreme Programming - Svetlin NakovAgile Methodologies And Extreme Programming - Svetlin Nakov
Agile Methodologies And Extreme Programming - Svetlin Nakov
 
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
 
Agile Methodologies And Extreme Programming
Agile Methodologies And Extreme ProgrammingAgile Methodologies And Extreme Programming
Agile Methodologies And Extreme Programming
 
Software Quality via Unit Testing
Software Quality via Unit TestingSoftware Quality via Unit Testing
Software Quality via Unit Testing
 

More from 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 best practices
Dev buchan best practicesDev buchan best practices
Dev buchan best practicesBill 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
 
12 Step Guide to Lotuscript
12 Step Guide to Lotuscript12 Step Guide to Lotuscript
12 Step Guide to LotuscriptBill 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
 

More from 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 best practices
Dev buchan best practicesDev buchan best practices
Dev buchan best practices
 
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
 
Ad505 dev blast
Ad505 dev blastAd505 dev blast
Ad505 dev blast
 
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
 
12 Step Guide to Lotuscript
12 Step Guide to Lotuscript12 Step Guide to Lotuscript
12 Step Guide to Lotuscript
 
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
 

The View - 30 proven Lotuscript tips

  • 1. 30 Proven Tips to Optimize Your LotusScript Development Bill Buchan HADSL © 2007 Wellesley Information Services. All rights reserved.
  • 2. What We’ll Cover … • Introduction • Theory • Practice • Advanced • Wrap-up 2
  • 3. Introduction • Who is the target audience?  Lotus Notes Developers • What is this about?  This talk aims to run through 30 different LotusScript tips  10 of these tips (“Theory”) are fundamental  10 of these tips (“Practice”) are what you should be doing  10 of these tips (“Advanced”) 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 for Enterprise customers  Learn from my pain!  5+ years code auditing  CEO – HADSL – developing best-practice tools 4
  • 5. What We’ll Cover … • Introduction • Theory • Practice • Advanced • Wrap-up 5
  • 6. Theory #1: Option Declare • You should always use “Option Declare” • Yes, but why?  If not, all variables are created at run-time as variants  This makes type-checking redundant  Data conversion costs ten times more performance!  And means all errors will be run-time errors  Remember: Test lots, test early  Use the strengths of the compiler to help you 6
  • 7. Theory #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. Theory #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. Theory #3: Application Lifecycle (cont.) Developer manager Dev edito r us er UAT a ger man Administrator manager Production 9
  • 10. Theory #4: “Measure Twice, Cut Once” • Spend more time thinking and less time coding • 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 when you wake up next to some code you don’t recognize.” – Bob Balaban 10
  • 11. Theory #5: Code Structure • Problem decomposition:  Smaller code sequences are easier to:  Maintain – the majority of the cost  Reuse – if kept simple  Rule of thumb: If its more than a screenful – can it be broken up?  But – don’t be prescriptive • It’s all about:  Problem decomposition  Maintainability  Code reuse  Get the data model right to start with! 11
  • 12. Theory #5: 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 12
  • 13. Theory #6: How to Code • How to code  Code for maintenance  Code updates cost more than new code  Architect well. Get the data model right to start with. • Only code for performance, if required  Get it working before getting it working for speed • Why?  The highest cost in development is software maintenance  Make it easier for the person maintaining the app  It could be YOU 13
  • 14. Theory #7: How to Test • Test soon, test often, test completely  Look at test-driven development  Write the specification  Write the structure  Write the tests  Write the code  Automatic testing means:  Far easier to regression test all the time  Minimize run-time errors by:  Always assuming that data operations outside the current database may fail  Trapping all run-time errors and providing an execution path that fails safely 14
  • 15. Theory #7: How to Test (cont.) • Why test early?  Costs rise as the tests fail further away from development  Cheapest to most expensive are:  Unit tests — by the developer  User acceptance tests (UATs) — by the tester  End-user failure — by the user  The more tests you perform in unit testing:  The cheaper your development will be  The more professional your colleagues will think you are  The more your boss will like you 15
  • 16. Theory #8: “Attitude” • The first rule of Best Practices is:  There is no Best Practice! • Seriously:  Don’t use Best Practices in a prescriptive manner  Examine each one and decide whether it makes sense in this context  Be open to new ideas • Attitude is better than prescriptive coding  No “Not invented here” syndrome  Collaborate  “The Lazy Programmer” 16
  • 17. Theory #9: Comments • Comments  Don’t over-comment – explain the “Why!”  I usually only comment non-intuitive algorithms  “This isn’t what you think … ” • A good use of comments is to write meta-code  For instance, when first writing a function, write the code- branches as a series of comments  Leave them in once the code is complete Function test (param1 as String, param2 as String) as integer ' check the parameters and bail out if incorrect. ' Add Param 1 to param 2 ' Check it’s valid. If so – update... ' Errorhandler end function 17
  • 18. Theory #9: Comments (cont.) • Remember:  Comments consume code space in LotusScript  There’s a 64k — about 1,400 line — limit for each code sequence  This should not normally be an issue  Classes, of course, are all declared in Declarations  In terms of classes, you can “subclass” to break up large class declarations • Check out LotusScript.doc:  www.lsdoc.org  It’s a “JavaDoc for LotusScript”  You can annotate code to make the comments clearer 18
  • 19. Theory #10: Error Handling • An Error is thrown at run-time when:  A resource is unavailable: Database, server, memory  File I/O breaks  Etc., etc. • Execution stops at the point of error • Sets error information:  Error$ — a textual description  Err — a numeric error code  Erl — the line number of the error • Jumps to the error handling routine  If there is no error handling routine in the current code sequence, jumps to calling function  If top-level function has no error handler, then default error handling is used 19
  • 20. Theory #10: Error Handling (cont.) • If an error occurs in the middle of a critical sequence of updates, possibly some updates will happen, and some will not  Serious data consistency errors  Get all your validation done before committing transactions  Perform all the transaction “commits” at the same time  In our case, all the “saves”  Defensive coding minimizes this effect  Do not use “on error goto next” • You must deal with errors 20
  • 21. Theory #10: Error Handling (cont.) • Two approaches:  Error trap in almost every routine  Very granular, lots of information  Minimal chance of breaking transactions  However, lots of code  Error trap at the top  Very simple, minimal code  You will lose context — you might not be able to get valid data on how the error happened  You might break transactions — and therefore compromise data integrity • I recommend:  Error trap in most routines! 21
  • 22. What We’ll Cover … • Introduction • Theory • Practice • Advanced • Wrap-up 22
  • 23. Practice #1: The List Operator Dim Pres list as String Pres(“George”) = “Bush” Pres(“Bill”) = “Clinton” Print “Georges’s last name is: “ + Pres(“George”) if not isElement(Pres(“Chad”)) then print “Chad wasn’t found” forall thisPres in Pres Print listtag(thisPres) + “ “ + thisPres 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 23
  • 24. Practice #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 24
  • 25. Practice #3: 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 25
  • 26. Practice #4: 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) run-time 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 application performance! 26
  • 27. Practice #4: Logging (cont.) • OpenLog is an OpenNTF Project:  www.openntf.org • It provides a framework for collecting error logging  To use in your database:  Copy the script libraries from the OpenLog database  Update the code: Function test(param1 as String) as integer Test = false on error goto errorhandler ' ... Test = true exitFunction: exit function errorhandler: call logError() resume exitfunction end function 27
  • 28. Practice #4: Logging (cont.) • Example OpenLog output: 28
  • 29. Practice #5: 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. 29
  • 30. Practice #6: 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!  And things always break on the 13th of the month 30
  • 31. Practice #7: 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 31
  • 32. Practice #8: Consuming Web Services • Two approaches: First, 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 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" 32
  • 33. Practice #8: Consuming Web Services (cont.) • Two approaches: Second, 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 33
  • 34. Practice #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 34
  • 35. Practice #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 … 35
  • 36. What We’ll Cover … • Introduction • Theory • Practice • Advanced • Wrap-up 36
  • 37. Advanced #1: Custom Classes • What are Custom Classes?  Custom 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  Custom Classes aid reusability  Pros: Good design methodology, leads to Java  Cons: “Different,” and takes time to sink in 37
  • 38. Advanced #1: Custom 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 38
  • 39. Advanced #2: 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 run-time  Pros: Flexibility, NO type checking  Cons: Performance, run-time errors Dim V as variant Dim S as new NotesSession set V = S.CurrentDatabase print V.getTitle() 39
  • 40. Advanced #2: Understanding Binding (cont.) Function ListCollection(p as variant) as integer test = false if (typeName(p) = “NOTESVIEW”) or _ (typeName(p) = “NOTESDOCUMENTCOLLECTION”) then ' decompose this collection into a number of ' single document calls to myself dim doc as NotesDocument set doc = P.getFirstDocument while (not doc is nothing) call listCollection(doc) set doc = p.getNextDocument(doc) wend else ' We've been passed a single document. ' Process it. Print “I have been passed doc: “ + doc.Title(0) test = true end if end function 40
  • 41. Advanced #3: Coding for Performance • Remember: Expensive operations include:  Opening databases and views  Documents with lots of fields • When collecting data:  Cache views where possible  Use NotesViewEntry instead of opening documents 41
  • 42. Advanced #3: Coding for Performance (cont.) • Performance 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” See also: Application Performance Techniques for Notes and Web Clients (Jamie Magee) 42
  • 43. Advanced #4: Lists and Custom Classes • Custom Classes bind complex data and operations • Lists look 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 43
  • 44. Advanced #5: 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 44
  • 45. Advanced #6: Encapsulation • Encapsulation allows us to include other complex types in our classes:  Allows you to collect different types of complex information class Department private headOfDepartment as Person private members list as Person as String private departmentname as String private Locations list as String … end class 45
  • 46. Advanced #7: 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() …. case 6 end class 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 46
  • 47. Advanced #8: LSI_Info()/GetThreadInfo • LSI_INFO() gives some run-time 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 ... 47
  • 48. Advanced #8: LSI_Info()/GetThreadInfo (cont.) ' calling code... ... ExitFunction: exit function errorhandler: Call RaiseError() Function RaiseError() resume exitFunction Dim thisType As String end function Dim es as String 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 48
  • 49. Advanced #9: 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?  Accommodates version/platform differences at run-time 49
  • 50. Advanced #10: Mixing Java and LotusScript • Use each language to its strengths:  Java – good for Web services, network I/O, multi-threaded 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 ... 50
  • 51. Advanced #10: Mixing Java and LotusScript … // Create a Script Library of type “Java” called xlib // containing the following function: public class calculator { Option Public public int add(int a, int b) { return a + b; } Use "xlib" 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 51
  • 52. What We’ll Cover … • Introduction • Theory • Practice • Advanced Tips • Wrap-up 52
  • 53. Resources • Homework:  Classes – my OO presentation  www.billbuchan.com/web.nsf/htdocs/BBUN6MQECQ.htm  Steve McConnell, “Code Complete, Second Edition” (Microsoft Press, 2004)  www.amazon.com/gp/product/0735619670  Duffbert’s presentation on Java  http://hostit1.connectria.com/twduff/home.nsf/htdocs/ TDUF5VAQSY.htm  Bob Balaban, “Programming Domino 4.6 with Java” (M&T Books, 1998)  http://www.amazon.com/gp/product/1558515836 53
  • 54. Resources (cont.) • LS 2004/AD104 – LotusScript Tips & Tricks  http://www-10.lotus.com/ldd/sandbox.nsf/ecc552f1ab6e46e 4852568a90055c4cd/68797abc4efa809a85256e51006a2c8a? OpenDocument&Highlight=0,AD104 • nsftools – Notes Tips  www.nsftools.com/tips/NotesTips.htm • The Notes FAQ!  www.keysolutions.com/NotesFAQ/ 54
  • 55. 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 • Articles in THE VIEW  André Guirard, “Speed up view development — A LotusScript agent to automatically create a view with fields from any form” (THE VIEW, July/August 2006)  Mikkel Heisterberg, “Self-documenting LotusScript code” (THE VIEW, January/February 2006) 55
  • 56. 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 56
  • 57. Your Turn! How to contact me: Bill Buchan Bill@hadsl.com 57