Best Practices in OO Lotus Script Final Draft [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

BP107 Best Practices for Object Orientated Lotusscript Bill Buchan Director, HADSL Premier Business Partner

1

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

2

What is “OO” Programming? z z It’s a way of writing large, complex systems in a

more intuitive manner z z 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) z z Its been in Lotusscript since its inception. z z It’s 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) z z Promotes Re-use ‹ ‹ The holy grail of software development ‹ ‹ Standard business components can be re-used. z z Look at the future ‹ ‹ Java anyone ? z z

4

How to use OO Methodologies ? z z Define a class ‹ ‹ Class

fred public mystring as String

sub new() me.myString = “Hello World” end sub end class z z Create one or “instances” of this class in

memory ‹ ‹ Dim

myFred as new Fred() print myFred.myString

5

Some OO Generalisations z z “Its difficult to use” - Not at all. z z “It’s a steep learning curve” – No z z 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. z z There is one class for each item in a system ‹ ‹ Probably not.

Try not to be too prescriptive in any architecture. z z It takes a couple of projects before you “get it”. ‹ ‹ This is probably true. “The “oo” moment.”

6

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

7

How to use OO within Lotusscript ? Use “Classes” to define objects. z z Use “new” and “delete” to create instances of classes ‹ ‹ Think of “notesDatabase” z z They bundle together ‹ ‹ members (properties) ‹ ‹ Functions and Subs (methods) z z 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 z z

8

OO Basics z z

Classes Classes are are defined defined by by wrapping wrapping them them with with ‹ ‹ “class [as ] ‹ ‹ “end class”

z z

The The classes classes are are all all defined defined in in the the “declarations” “declarations” section section of of aa Lotusscript Lotusscript code code sequence. sequence. ‹ ‹

z z

Remember. Remember. R5 R5 –– 64 64 limit. limit. R6 R6 –– bigger. bigger. ND7 ND7 -- Best Best

When When aa class class is is constructed constructed ‹ ‹ The “sub new()” function (the constructor) is called

for this class, and all its parent-classes „ „ The The top-most top-most parent parent class class constructor constructor is is called called first firstWhen When aa class class is is deleted deleted

‹ ‹ The “sub delete()” (the destructor) function is called z z

You You cannot cannot extend extend subclasses subclasses from from base base “notes…” “notes…” classes. classes.

9

OO Basics z z 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) z z 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 Class animal animal Private Private myName myName as as String String Sub Sub new() new() me.myName me.myName == “Animal” “Animal” End sub End sub

Private Member Constructor Constructor

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

Dog inherits from class “Animal” Public Member Overridden Constructor

11

OO Basics – some best practices z z Each class contained in a different script library z z Don’t expose your internal properties ‹ ‹ Declare them as “private”!

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

z z Keep the classes small. ‹ ‹ Large classes mean that you should split them up

„ „ that that you you probably probably aren't aren't re-using re-using things things as as much much as as you you can can z z Always Architect before optimising 12

Agenda z z Why use Object Orientated Methodologies? z z OO Basics in Script z z Demo OO application – Directory Compare z z Extend or Encapsulate ? z z Large OO projects z z Pitfalls and Tricks z z 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”

Library names are case sensitive on non-wintel platforms!

Dim P as new person(doc) Print “This persons name is: “ & P.personName.Abbreviated

15

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

16

Extend or Encapsulate ? z z 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 z z Encapsulating a class ‹ ‹ makes a new class more useful by using other

classes within it…

17

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

18

So how do I use personCollection? Dim Dim PC PC as as new new PersonCollection PersonCollection Dim Dim doc doc as as NotesDocument NotesDocument Set Set doc doc == myView.getFirstDocument myView.getFirstDocument While While Not Not (doc (doc is is nothing) nothing) dim dim P1 P1 as as new new Person(doc) Person(doc) call call PC.addPerson(P1) PC.addPerson(P1) set set doc doc == myView.getnextDocument(doc) myView.getnextDocument(doc) Wend Wend …… Dim Dim PP as as person person Set Set PP == PC.findPerson(“Joe PC.findPerson(“Joe Bloggs/Acme”) Bloggs/Acme”) If If Not Not (P (P is is nothing) nothing) then then print print “found “found person: person: ““ && P.PersonName.Abbreviated P.PersonName.Abbreviated End End if 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 z z We’ll 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. z z Why does this help ? ‹ ‹ We only load the Person Documents once

z z We can further improve this by: ‹ ‹ Using NotesViewEntryCollection instead of notesView

22

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

23

Demo – Directory Comparison Tool

24

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

25

Large OO Projects z z How to design large OO projects z z Consider various approaches, and iterate

towards a good OO architecture. z z Good design and architecture is better than coding z z Use skeleton classes to mimic behaviour ‹ ‹ Allows early integration ‹ ‹ Allows you to finalise class structure quickly

z z Unit test each class. ‹ ‹ And keep unit testing them to prevent regressions

26

Large OO Projects … z z 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!

z z 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, don’t change

them! Add more methods, but don’t modify. z z You may have to do several OO applications

before you “get it”. 27

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

28

Pitfalls – Fixup Time on Load z z Remember, LotusScript is a p-code compiled,

interpreted language ‹ ‹ Similar to Java

z z Lotusscript has some “loose” data constructs: z z This means that Fixup Time is significant. ‹ ‹ What is fixup time ? „ „ The The time time taken taken to to load load all all modules, modules, and and to to resolve resolve all all variables. variables. In In traditional traditional compiled compiled programs, programs, this this was was performed performed by by the the linker linker at at executable executable build build time. time. ‹ ‹ How does this affect me ? „ „ The The more more complex complex your your applications, applications, the the longer longer itit takes takes –– almost almost geometrically geometrically –– to to load. load. (this (this applies applies to to ALL ALL code, code, not not just just classes) classes) „ „ Example: Example: 20 20 classes classes –– 44 seconds seconds load load time. time. 120 120 classes classes –– 145 145 seconds seconds load load time. time.

29

Fixup time ?

Time (Seconds) (Seconds) Time

Fixup Fixup time time vs vs Complexity Complexity

Complexity Complexity

30

How to code around it z z Fixup time doesn’t have significant impact

before 20+ classes and/or script libraries (in my experience) ‹ ‹ My Example: 120+ classes – 145 seconds to load.

z z 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 Demands programming programming discipline discipline and and rigour! rigour!

31

Dynamic Loading reference z z Dynamic loading is a technique outlined in

Redbook ‹ ‹ “Performance Considerations for Domino

Applications” ‹ ‹ SG24-5602 ‹ ‹ Buried in Appendix B, Page 243 z z Numerous Gary Devendorf Web Services

examples

32

Dynamic Loading Example Private Private PP as as variant variant

‘‘ This This HAS HAS to to be be global! global!

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

Script library “class:fred” looks like: The ‘Factory’ Version of this class exists only to create a new instance of the main class

Class FredFactory Public Function produce As Variant Set produce = New Fred End Function End Class Class Fred … End 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 z z Always have one class that knows how to

construct the rest WITHOUT using the “use” directive. ‹ ‹ A “Factory” class, for instance.

z z You don’t have to dynamically load ALL classes. ‹ ‹ Common classes such as “log” or “config” are

always normally resident z z 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 ? z z Remember – you’re loading a class you decide

at RUN TIME z z You can load separate classes depending on: ‹ ‹ Version, Platform, Capability, User permission, Your

data! z z 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. z z Use Classes to do the work for you!

37

Compilation Woes Expect Compilation Complexity. z z For instance, consider the fairly simple class structure z z

Agent 1

Agent 2

Agent 3

Agent 4

Routines:Examples Class Factory

Class PersonCollection Class Person

38

Compilation Woes z z

Change Change aa subclass subclass deep deep in in the the inheritance inheritance hierarchy hierarchy and and you you will will probably: probably: ‹ ‹ See Server Console AMGR message or client dialog:

z z z z

„ „ “11/23/2004 “11/23/2004 12:03:03 12:03:03 PM PM Agent Agent '(Blah)' '(Blah)' error: error: Error module: cl_event_v2 cl_event_v2 Error loading loading USE USE or or USELSX USELSX module: „ „ “Error “Error %s %s ““ Why Why ? ? The The signature signature of of the the subclass subclass has has changed… changed… How How to to resolve resolve ? ? ‹ ‹ Tools, Compile all Lotusscript. ‹ ‹ Similar to Java. Most java IDE’s will rebuild all when

significant change is spotted. z z Dynamic loading completely sidesteps this

issue

39

Code Hiding The “Hide Design” database property can sometimes be too restrictive. z z Should all of your commercial code be in script libraries, then: z z

‹ ‹ ‹ ‹ ‹ ‹ ‹ ‹

Find Find the the script script library’s library’s design design document document Replace Replace item item “ScriptLib” “ScriptLib” with with some some text text such such as as “© “© MyName, MyName, 2004” 2004” The The end-user end-user cannot cannot recompile recompile the the library library –– and and cannot cannot see see your your code. code. Warning. Warning. No No way way back back (obviously). (obviously). So So do do this this on on your your BUILD BUILD copies copies of of templates, templates, not not your your development development templates templates

40

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

41

Summary z z OO is a simple, pain-free way of building and

maintaining large Domino Projects. z z OO should be part of your toolset during application design z z Lotusscript can do large, serious and complex OO projects

42

Related Sessions and Resources z z Redbook: “Performance Considerations for Domino

Applications” ‹ ‹ Search for SG24-5602 at http://www.lotus.com/redbooks

z z Notes.net Article: ‹ ‹ “Using the object-orientated features of Lotusscript”

by Bruce Perry, from October 2001.

z Dev.kaangard.net ‹ ‹ http://dev.kanngard.net/dev/home.nsf/ArticlesByTitle/LSClass.html z z OpenNTF ‹ ‹ Check out OpenDom by Alain H Romedenne ‹ ‹ http://www.openntf.org

43

Related Sessions and Resources z z Book: Code Complete 2, Steve McConnell, MS

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

44

Questions? z z Please fill out your evaluations z z 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” z z Check out our product – iDM ‹ ‹ http://www.hadsl.com

z z Thanks for coming!

45