As you recall (possibly because I keep going on about it), I presented on OO Lotusscript at Lotusphere 2006 this year. (The presentations are on the HADSL website here)
Today one of the people who watched my
performance presentation asked me:
.. I am intrigued by the possibilities of what creating my own classes might do, but I can't seem to get into my mind what the major advantage of using the classes is over being able to utilize the script libraries.
If relate the class to the library, I can see where the subs and functions I create within the library are related to the properties and methods I create under a class. Quite frankly, it is much easier for me to follow and find the subs and functions in the library versus the class. So what is the difference that I am missing that will make it quite clear when and why to use my own classes versus just putting them in libraries?
A very good question indeed ! And one which I had insufficiently explained in my session. However, I think a long answer is required.
Object orientated programming is bit of a mind shift.
In Lotusscript right now, your dealing with a single-threaded program flow. So no matter how we dress it up - it can still all be done with SUBS and Functions. (In Java - you'll find - you can have far more fun with multi-threading,etc. Because you have multiple threads running - you have to ensure that your data cannot be tainted by another thread.)
Now - at some point during your design decomposition of your problem set, you'll have realised that various blobs of information need to be carried around the system. The example I use is a simple version of a person object, for the purpose of directory synchronisation. Which works.
It gets increasingly more and more difficult to update code, if your passing around 3, 4, or five, or more bits of information to sub-functions. Your "tight" binding where a lot of assumptions about the design of your system has been expressed in terms of how functions get called, etc. Imagine the pain if one of those items of information changed type (say string to integer, or string to Notesname). How many pieces of code would have to change and where ? Ouch.
If you take a slightly different Object Orientated approach, you'll see that with this "clump" of data - say - a person object - there's various functions that you'll need, in order for other things to use this object. Typically, you should have some way of creating this thing, some interaction with the thing and some way of updating the thing.
Most of the functions that interact with this clump of data are intimately aware of how you've chosen to represent this data. If you change how the data gets represented - for instance, using a NotesName field instead of a string for the name - then life gets more complicated.
In an OO world, we clump all the functions and the data into a class, and then can create multiple copies of that class in memory. It makes it far easier to create a "person" (assuming you created your own "Person" class) if all you have to do is:
dim P as new Person(myNotesDocument)
And when you start to use "lists".. (if you don't use lists, please look them up. They've very cool. In fact, check out: my article on Lists for more information )
So for instance, if we can get the persons name out of a person document using GetName, we could easily:
dim personList list as Person
'' And then some loop enumerating documents
Dim P as new Person(myNotesDocument)
set personList(P.getName) = P.
All of a sudden, you have the ability to very quickly hold ALL people in memory. If one person is called "Joe Bloggs/Acme", then you might find him using:
print "Joe: " + personList("Joe Bloggs").getName()
Now. All the stuff that knows how person is made up is within the person class. So internally if you originally defined the INTERNAL name component as a string:
private myName as String
public function getName as String
getName = myName
you could easily change it to use NotesName internally:
private myName as notesName
public function getName as String
' If we've not defined the name - return here. It'll pass back an empty string
if (myName is nothing) then exit function
getName = myName.Abbreviated
(The bits in bold are the only pieces I'm changing)
As you've forced everyone to use "Person.GetName" to get this person objects name - you can switch around how the internals work, and as long as the interface to the outside world hasnt changed - no-one is any the wiser.
A statement that I'm sure we'll all agree with. Simple code is easy to maintain. Software maintenance is one of the highest costs associated with business applications - and the simpler we make applications to maintain, the lower the costs. Simple can be expressed as "short", well-structured, re-usable, maintainable.
So - object orientated programming:
- Keeps it simple. (possibly) Short code sequences in the class. Code-hiding means that most of your implementation is hidden from the users of you class.
- Keeps data with relevant code. So if the data changes, so can the code.
- Allows you to maintain defined interfaces between components
- Simplifies by code-hiding. No-one has to know exactly how you implement a class - just as long as its external interface - its "signature" is consistent.
Now lastly, in terms of "why not just use functions and subs in a script library". Yes. If the script library keeps no "global" data within the script library, then no worries. But once you start keeping global variables inside the script library, you have to worry about two separate "instances" of that data should you wish to call it twice.. and so forth. So classes win again in this respect, by keeping separate copies of data instances away from each other.
I hope this has been a useful addition to the discussion on OO techniques in Lotusscript - please shout if you have any comments on this!
Two books you should consider purchasing right now: