You are on page 1of 45

BP107 Best Practices for Object Orientated Lotusscript

Bill Buchan Director, HADSL Premier Business Partner

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

What is OO Programming?
Its a way of writing large, complex systems in a more intuitive manner The core assumptions are:
Most objects will represent actors or processes in a business problem You do not need to know how an object is implemented in order to use it. (Information Hiding)

Its been in Lotusscript since its inception. Its a different way of breaking down problems.
Compared to structured programming It requires more thought during architecture It requires less work during implementation (in a well architected system)
3

Why use OO Methodologies ?


Maintainability & Robustness Small code sequences are easier to maintain Code hiding lends to better componentisation and design Loose Coupling is better than tight coupling. Classes can be tested in a stand-alone basis before integration with other components. It can help you test sooner (and should be considered best practice) Promotes Re-use The holy grail of software development Standard business components can be re-used. Look at the future Java anyone ?

How to use OO Methodologies ?


Define a class
Class fred public mystring as String sub new() me.myString = Hello World end sub end class

Create one or instances of this class in memory


Dim myFred as new Fred() print myFred.myString

Some OO Generalisations
Its difficult to use - Not at all. Its a steep learning curve No There is no benefit.
Untrue. From a medium to large scale project, getting it right from the start means more code reuse, more robust applications, and less effort.

There is one class for each item in a system


Probably not. Try not to be too prescriptive in any architecture.

It takes a couple of projects before you get it.


This is probably true. The oo moment.

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

How to use OO within Lotusscript ?


Use Classes to define objects. Use new and delete to create instances of classes Think of notesDatabase They bundle together members (properties) Functions and Subs (methods) Classes can be based on other classes In which case they inherit all the properties and functions of the parent class More on this later

OO Basics
Classes are defined by wrapping them with Classes are defined by wrapping them with

class <name> [as <parentClass>] end class


The classes are all defined in the declarations section of a The classes are all defined in the declarations section of a Lotusscript code sequence. Lotusscript code sequence.
Remember. R5 64 limit. R6 bigger. ND7 - Best Remember. R5 64 limit. R6 bigger. ND7 - Best

When a class is constructed When a class is constructed

The sub new() function (the constructor) is called for this class, and all its parent-classes
The top-most parent class constructor is called firstWhen The top-most parent class constructor is called firstWhen
a class is deleted a class is deleted

The sub delete() (the destructor) function is called


You cannot extend subclasses from base notes classes. You cannot extend subclasses from base notes classes.

OO Basics
You can define items within a class as
Public anything else can use this property or method Private only the class itself (or any subclasses) can use this property or method)

You can extend or subclass classes


For instance, the class Animal could be extended by class dog, which is a more precise version of the class Class dog shares and re-uses all properties and methods from Animal. Class dog may OVERRIDE methods within animal Class dog may provide MORE properties and methods than class ANIMAL.

10

Example: Animal and Dog


Class animal Class animal Private myName as String Private myName as String Sub new() Sub new() me.myName = Animal me.myName = Animal End sub End sub Public function getName() as String Public function getName() as String getName = me.myName getName = me.myName end function end function Public function getSpecies() as String Public function getSpecies() as String getSpecies = Animal getSpecies = Animal End function End function End class End class Class Dog as Animal Class Dog as Animal Public masterName as String Public masterName as String sub new() sub new() me.myName = Dog me.myName = Dog end sub end sub End class End class

Private Member Constructor Constructor

Dog inherits from class Animal Public Member Overridden Constructor

11

OO Basics some best practices


Each class contained in a different script library Dont expose your internal properties
Declare them as private!

Use Me. to resolve ambiguity You can use property get & set constructs.
Functions that look like class properties Advise against it

Keep the classes small.


Large classes mean that you should split them up
that you probably aren't re-using things as much as you that you probably aren't re-using things as much as you can can

Always Architect before optimising


12

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

13

OO Basics. The Person Class


Class Person Public PersonName as NotesName Public DominoDomain as String Private UNID as String sub new(doc as notesDocument) set me.PersonName = new NotesName(doc.FullName(0)) me.DominoDomain = doc.Domain(0) me.UNID = doc.UniversalID end sub End class

14

So how do I use this ?


Use class:personClass Dim P as new person(doc)

Library names are case sensitive on non-wintel platforms!

Print This persons name is: & P.personName.Abbreviated

15

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

16

Extend or Encapsulate ?
Remember: Extending class
takes a class, makes a new class from it, but inherits all properties and methods You can override original class methods You cannot overload methods (as Java can) You can add new methods And of course you can extend to any depth

Encapsulating a class
makes a new class more useful by using other classes within it

17

Make this more useful by Encapsulation


Class PersonCollection Class PersonCollection private people list as Person private people list as Person public sub addPerson(P as Person) public sub addPerson(P as Person) set me.people(P.PersonName.Abbreviated) = P set me.people(P.PersonName.Abbreviated) = P end sub end sub public function findPerson(userName as String) as Person public function findPerson(userName as String) as Person set findPerson = nothing set findPerson = nothing if (isElement(me.people(userName))) then if (isElement(me.people(userName))) then set findPerson = me.people(userName) set findPerson = me.people(userName) end if end if end function end function End class End class

18

So how do I use personCollection?


Dim PC as new PersonCollection Dim PC as new PersonCollection Dim doc as NotesDocument Dim doc as NotesDocument Set doc = myView.getFirstDocument Set doc = myView.getFirstDocument While Not (doc is nothing) While Not (doc is nothing) dim P1 as new Person(doc) dim P1 as new Person(doc) call PC.addPerson(P1) call PC.addPerson(P1) set doc = myView.getnextDocument(doc) set doc = myView.getnextDocument(doc) Wend Wend Dim P as person Dim P as person Set P = PC.findPerson(Joe Bloggs/Acme) Set P = PC.findPerson(Joe Bloggs/Acme) If Not (P is nothing) then If Not (P is nothing) then print found person: & P.PersonName.Abbreviated print found person: & P.PersonName.Abbreviated End if End if

19

Lets improve PersonCollection


Class PersonCollection public Function loadAllDocsInView(mV as NotesView) dim doc as NotesDocument set doc = mV.getFirstDocument while Not (doc is nothing) dim P as new Person(doc) call me.addPerson(P) set doc = mV.getNextDocument(doc) wend end function end class

20

New example code.


Dim PC as new PersonCollection Call PC.loadAllDocsInView(myView) . Dim P as person Set P = PC.findPerson(Joe Bloggs/Acme) If Not (P is nothing) then print found person: & P.PersonName.Abbreviated End if

21

Now lets use PersonCollection


Well use this example class to quickly compare two domino directories.
Open both directories, and views in each database Create a new PersonCollection from each view. Iterate through the first PersonCollection, and check to see that this person is in the second view. And vice versa.

Why does this help ?


We only load the Person Documents once

We can further improve this by:


Using NotesViewEntryCollection instead of notesView

22

An interesting observation
Class PersonCollection Class PersonCollection public Function loadAllDocsInView(mV as Variant) public Function loadAllDocsInView(mV as Variant) dim doc as NotesDocument dim doc as NotesDocument set doc = mV.getFirstDocument set doc = mV.getFirstDocument while Not (doc is nothing) while Not (doc is nothing) dim P as new Person(doc) dim P as new Person(doc) me.addPerson(P) me.addPerson(P) set doc = mV.getNextDocument(doc) set doc = mV.getNextDocument(doc) wend wend end function end function end class end class

23

Demo Directory Comparison Tool

24

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

25

Large OO Projects
How to design large OO projects Consider various approaches, and iterate towards a good OO architecture. Good design and architecture is better than coding Use skeleton classes to mimic behaviour
Allows early integration Allows you to finalise class structure quickly

Unit test each class.


And keep unit testing them to prevent regressions

26

Large OO Projects
Its *never* completely correct
Beware tightly bound mutually dependant classes! Remember that specifications change over time. Architect for clarity and maintenance. Performance is an implementation consideration!

If you have to change class methods frequently


You are exposing weaknesses in the design phase You are open to regression errors Once methods behaviour are finalised, dont change them! Add more methods, but dont modify.

You may have to do several OO applications before you get it.


27

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

28

Pitfalls Fixup Time on Load


Remember, LotusScript is a p-code compiled, interpreted language
Similar to Java

Lotusscript has some loose data constructs: This means that Fixup Time is significant.
What is fixup time ?
The time taken to load all modules, and to resolve all variables. In The time taken to load all modules, and to resolve all variables. In traditional compiled programs, this was performed by the linker at traditional compiled programs, this was performed by the linker at executable build time. executable build time.

How does this affect me ?


The more complex your applications, the longer it takes almost The more complex your applications, the longer it takes almost geometrically to load. (this applies to ALL code, not just classes) geometrically to load. (this applies to ALL code, not just classes) Example: 20 classes 4 seconds load time. 120 classes 145 Example: 20 classes 4 seconds load time. 120 classes 145 seconds load time. seconds load time.

29

Fixup time ?
Fixup time vs Complexity Fixup time vs Complexity

Time (Seconds) Time (Seconds)

Complexity Complexity

30

How to code around it


Fixup time doesnt have significant impact before 20+ classes and/or script libraries (in my experience)
My Example: 120+ classes 145 seconds to load.

Use loose binding instead of tight binding.


Use Variants to hold and pass classes Use Dynamic Loading to instantiate classes After implementation, same 120+ classes 15 seconds. Downside. No more type checking!
Demands programming discipline and rigour! Demands programming discipline and rigour!

31

Dynamic Loading reference


Dynamic loading is a technique outlined in Redbook
Performance Considerations for Domino Applications SG24-5602 Buried in Appendix B, Page 243

Numerous Gary Devendorf Web Services examples

32

Dynamic Loading Example


Private P as variant Private P as variant This HAS to be global! This HAS to be global! Function createOtherClass_ Function createOtherClass_ (scriptName as String, className as String) as variant (scriptName as String, className as String) as variant Dim exString as String Dim exString as String exString = | Use | & scriptName & | This string contains exString = | Use | & scriptName & | sub initialize Lotusscript code sub initialize Set P = new | & className & |Factory & Set P = new | & className & |Factory & end sub | end sub | Execute exString Now run the code in exString Execute exString Now run the code in exString Set createOtherClass = P Set createOtherClass = P End sub End sub Sub DynamicLoadingExample Sub DynamicLoadingExample dim myClass as variant dim myClass as variant set myClass = createotherClass(class:fred, fred) set myClass = createotherClass(class:fred, fred) End sub End sub
33

Script library class:fred looks like:


Class FredFactory Public Function produce As Variant Set produce = New Fred End Function End Class Class Fred End class
The Factory Version of this class exists only to create a new instance of the main class

There are no constructor arguments being passed to class fred. This will have to be changed if you choose to add constructor arguments.
34

Dynamic Loading OO Architecture


Always have one class that knows how to construct the rest WITHOUT using the use directive.
A Factory class, for instance.

You dont have to dynamically load ALL classes.


Common classes such as log or config are always normally resident

You can dynamically load different classes.


Based on Notes/Domino version, Platform, Data Using one dynamic load function means you have to use the same signature on the class constructor

35

Dynamic Loading OO Example


Factory Request Log Configuration

User Create v5 User Create v6 User Create UI User Create Profile

36

Hang on you had a v5 class ?


Remember youre loading a class you decide at RUN TIME You can load separate classes depending on:
Version, Platform, Capability, User permission, Your data!

Different version classes can inherit from each other


So your version 6 class inherits from the version 5 class Or your AIX class inherits from your core class Only overrides the functions that need to be different.

Use Classes to do the work for you!


37

Compilation Woes
Expect Compilation Complexity. For instance, consider the fairly simple class structure
Agent 1 Agent 2 Agent 3 Agent 4

Routines:Examples Class Factory

Class PersonCollection Class Person

38

Compilation Woes
Change a subclass deep in the inheritance hierarchy and you Change a subclass deep in the inheritance hierarchy and you will probably: will probably:

See Server Console AMGR message or client dialog:


11/23/2004 12:03:03 PM Agent '(Blah)' error: 11/23/2004 12:03:03 PM Agent '(Blah)' error: Error loading USE or USELSX module: cl_event_v2 Error loading USE or USELSX module: cl_event_v2 Error %s Error %s Why ? The signature of the subclass has changed Why ? The signature of the subclass has changed How to resolve ? How to resolve ?

Tools, Compile all Lotusscript. Similar to Java. Most java IDEs will rebuild all when significant change is spotted.

Dynamic loading completely sidesteps this issue

39

Code Hiding
The Hide Design database property can sometimes be too restrictive. Should all of your commercial code be in script libraries, then:
Find the script librarys design document Find the script librarys design document Replace item ScriptLib with some text such as Replace item ScriptLib with some text such as MyName, 2004 MyName, 2004 The end-user cannot recompile the library and cannot The end-user cannot recompile the library and cannot see your code. see your code. Warning. No way back (obviously). So do this on your Warning. No way back (obviously). So do this on your BUILD copies of templates, not your development BUILD copies of templates, not your development templates templates

40

Agenda
Why use Object Orientated Methodologies? OO Basics in Script Demo OO application Directory Compare Extend or Encapsulate ? Large OO projects Pitfalls and Tricks Summary and questions

41

Summary
OO is a simple, pain-free way of building and maintaining large Domino Projects. OO should be part of your toolset during application design Lotusscript can do large, serious and complex OO projects

42

Related Sessions and Resources


Redbook: Performance Considerations for Domino Applications
Search for SG24-5602 at http://www.lotus.com/redbooks

Notes.net Article:
Using the object-orientated features of Lotusscript by Bruce Perry, from October 2001.

Dev.kaangard.net
http://dev.kanngard.net/dev/home.nsf/ArticlesByTitle/LSClass.html

OpenNTF
Check out OpenDom by Alain H Romedenne http://www.openntf.org

43

Related Sessions and Resources


Book: Code Complete 2, Steve McConnell, MS Press. Book: The Pragmatic Programmer, Addison Wesley Book: Understanding Object-Oriented Programming With Java Timothy Budd AD101 What 's New in Lotus Domino Designer? AD211 Leveraging the Power of Object Oriented Programming in LotusScript

44

Questions?
Please fill out your evaluations Remember you can ask me more questions in:
Toucan 2 for the next hour Guru-Pazoola in the Swan at 10:30am all Best Practices Speakers will be there. By sending me mail to Bill at BillBuchan.com

Check out our product iDM


http://www.hadsl.com

Thanks for coming!

45

You might also like