Wednesday, September 03, 2008

My take on the truth : part 3

Nathan asked the question "So how do you maximise the adaptability of your solution". Ironically, this post has been 'brewing' in draft for some time, so it's timely that the third truth has popped up in time for me to post it.

One of the concepts of XP is "do the best today, striving for the awareness and understanding necessary to do better tomorrow", which in essence is what we want to achieve by having adaptable (or agile) solutions. To have a solution designed and developed in such a way that incremental changes (refactoring) to meet new needs is not an major deal. I'm not saying adopt XP or Agile techniques and magically your solution will be agile. 

So what am I saying, and what has XP and Agile got to do with Notes and Domino development ?

The most important thing for me is the mindset of XP and Agile. When I approach development I start by considering what is absolutely necessary to get a solution, but being mindful of potential unknown future requirements. Sort of future proofing the solution in design, but only implementing what is needed for today. It's a guessing game, sure, but with experience you get better at anticipating those areas. In XP this is the simple principle, "What is the simplest solution that could work". This is not deliver on minimal spec or cutting corners so that you are locked in to an incorrect approach.

Using Object Oriented (OO) techniques in your code can allow you to be more agile when refactoring and can provide good reuse. However, there is a trap.

In OO you can sometimes trip up and try to implement every possible feature in a class. Something that I did, when reuse was king and Lotus Notes 4.6 was the latest version. For your solution today, some of what you develop for ultimate reuse may not be necessary today.  In effect you are adding additional complexity for what you actually need right now - and your effort may never be used - wasted. Don't get caught in the trap of building the perfect class with every possible method/feature or property that anyone could ever want. 

Now, this doesn't mean doing a half baked job or locking yourself into an approach. (37 signals have an interesting take on this - read the article). It does mean being brutal about what to include and what not to include. Which means that you can spend time on the bits that you do need, ensuring that what you deliver is of a better quality.

All of this is just a bunch of nice concepts and buzz words - show me the code, I hear you ask. So here, in code, is one example of how I did this with LotusScript.

In the first version of our web content system, I needed to be able to send Mime messages. The message template was stored as XML/XHTML template in a document. 

I created a generic MimeMessage class to handle the construction and sending of a HTML message. I didn't start by trying to implement every Mime feature based on the spec. I just wrote  what I needed. I implemented a SCMTemplateMailMessage to wrap the retrieving of the template XML and Mime message creation so that the code in my agents and actions looked like this.

Dim confirmMessage As SCMTemplateMailMessage
Set confirmMessage = New SCMTemplateMailMessage(session,noteProcessed)
Call confirmMessage.SendMessage("register_confirm")

Later aother client, for a different website, based on the same CMS code required a weekly report of registrations in a CSV file. I extended the SCMTemplateMailMessage to a SCMTemplateReportMailMessage, which sourced the recipient list stored with a refactored template document. 

I also needed to send Mime attachments, I refactored the MimeMessage class to include three new member variables and a new method, to store the filename ready for attaching.

MimeMessage.addAttachment(filename As String, stype As String, displayName As String)

This was then called from the method.

When I looked at the way in which to generate attachments, the type "text/csv", seemed something that in the future might change. I included this a seperate parameter for the mime type - designing some flexibility for the future.

Later on a new requirement surfaced where a mime messages with two pdf attachments needed to be sent.

I refactored the MimeMessage class again. I updated the inner workings, by changing the member variables to be an array of files, types and display name. This then allowed the adding of multiple attachments which could be pdfs or some other file type. 

The code in the new agent, for sending pdf reports looks like so.

Set confirmMessage = New SCMTemplateMailMessage(session,note)
Call confirmMessage.appendAttachment("file1.pdf","application/pdf")
Call confirmMessage.appendAttachment("file2.pdf","application/pdf")
confirmMessage.SendTo =
Call confirmMessage.SendMessage("personal_performance")

When I started building the MimeMessage class, I had no idea that I might need to send attachments let alone multiple attachments. The code was refactored to include new features and functionality and allowed me to quickly add additional features.

Of course this is a LotusScript example, but the same is true for other elements if you look at how you can use shared subforms, columns, actions and fields and file resources - there are  ways that you can design agility into your solution. Notes provides a lot of functionality that helps agility and for me it's a sweet spot for the type of applications that I deliver.

Build for today, Design for tomorrow.

That's how I ensure my solutions are adaptable and I'm looking forward to seeing 'the truth:part 4'