Email Me
my first name at my last name dot com

Archives
Past Blog Entries

Links
Andy Wrenbeck
ApplePhoneShow
Ben Abler
Ben Poole
Bob Lutz
Bob Obringer
Bruce Elgort
Carpeaqua
Codestore
Cult of Mac
Daring Fireball
Detroit News
Domino Unplugged
Ed Brill
Guidebook
I, Cringely
Joe Litton
Jonvon
NSFTools
NSLog
Ned Batchelder
Old Blog
Raymond Chen
Scobleizer Weblog
Techdirt
Unsanity
Weblogs Apple Log
bonj

11/12/06 9:45 PMImplementing a factory pattern in LotusScript

I recently had a need to implement a factory style pattern in LotusScript and I thought it might make an interesting topic for an article.

Here is the scenario:

This company wants to make a change to the standard Lotus Notes mail template. Of course, this change has to be as lightweight as possible, since playing with the mail template at all is asking for trouble. To make the scenario even more interesting, the Notes mail template is controlled by the parent company of this Notes shop. Getting a change made to the mail template becomes a very big deal. Finally, word comes down from high up that unless we can get this change in place, heads will role.

So, how do you update the mail template with the absolute least amount of impact on the template itself? The solution was to implement a factory pattern, slightly modified, in LotusScript. The change that we needed to make was to alter the processing of a calendar event entry when that event came from a customer of this company. Keeping in mind that this is a shared template and we only want to alter the processing when the document comes from one specific company and is received by a member of this company and not the parent company or any other affiliate which also happens to be using the common template.

The solution I came up with only requires a single line of code to be changed in the base template. The rest of the code will exist in a stand alone script library, which can be maintained outside the base template. So, before digging into the script libary, I will discuss the template change.

The change was on the "Notice" form. In the QueryOpen event for the form, this line of code was used to create an instance of the CSEventNotes class, which is used within the code throughout the rest of the form:

Set csEventObj= New CSEventNotes( 1, source.document, source )

Rather than using this line of code, I replaced it with a call to my factory function:

Set csEventObj = ABCEventClassFactory( 1, source.document, source )

Technically, there is a second line of code which is also needed, which tells the form to use my new script library with the factory function and the overridden class:

Use "ABCCSEventNotes"

That is the extent of the changes that were required to be made to the base design of the template. It should be noted that the custom class must be a subclass of the CSEventNotes class. A new script library was created with the above name. The library contains two things. One, a new class which extends the CSEventNotes class to override the functionality. Second, the factory function is defined. Here is the function:

Function ABCEventClassFactory(nEventType As Integer, note As notesdocument, source As notesuidocument) As CSEventNotes
Dim abccheck As Boolean
On Error Goto returnstandard
abccheck = False
Dim fromstring As Stringfromstring = Ucase(note.GetItemValue("From")(0))
If ( Instr(fromstring, "@XYZ.COM") > 0 ) Then
abccheck = True
End If

If (abccheck = True) Then
Set ABCEventClassFactory = New ABCCSEventNotes( 1, source.document, source )
Else
Set ABCEventClassFactory = New CSEventNotes( 1, source.document, source )
End If

theend:
Exit Function

returnstandard:
Set ABCEventClassFactory = New CSEventNotes( 1, source.document, source )

Resume theend
End Function

There are a couple of notes about this function that I wanted to make. If some sort of error happens trying to figure out what to do, then I want to play it safe and return an instance of the CSEventNotes class. Second, the more hardcore coders out there will be wondering why I have two if statements when appears that it could be simply done in a single if. Its really a simple answer. The real code has more complex logic to determine which class should be returned. Most of the business logic code was stripped out for this example.

In a nutshell, what this function does is make some decisions about which class the user needs based on some sort of business logic. This could be easily extended to return a wide variety of different classes to meet different needs. I have effectivity isolated the specific implementation of the business logic from the calling object, which is the Notice form in this case. This is really the essence of the factory pattern.

To finish the story, lets look at a sample implementation of the ABCCSEventNotes class. What I want is to change the standard CSEventNotes class to change the behavior of the SubProcessAction method. This sample code demonstrates how the customization would look.

Class ABCCSEventNotes As CSEventNotes
Sub New (nEventType As Integer, note As notesdocument, source As notesuidocument), CSEventNotes( nEventType, note, source)
'nothing required, let the CSEventNotes constructor handle everything
End Sub

'This is the override of the CSEvent ProcessAction method
Sub ProcessAction(vArgs As Variant)
...
...End Sub
End Class

The class needs to have a constructor (New) method, although it is not doing to do anything specific in this case. The constructor simply calls the parent (CSEventNotes) constructor and then does nothing. There is only one method from the parent class which needs to be overridden. That is the ProcessAction sub.

I hope this article provides a good example of using Object Orientated concepts in LotusScript to solve problems in a low impact, low risk way.

Ed Wrenbeck // Add a comment // link

Current Articles
Fluorescent Application Download
Implementing a factory pattern in LotusScript
Using AWStats and Tomcat
Using LotusScript to add subforms to a form
Installing FlowBuilder 3.0 on Linux (SuSE 9.1)
NSOutlineView and Tooltips and Java
The technology behind the site
How do I get Pi Messenger?

login