Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Sunday, 26 February 2012

How Much Architecture is Enough?

In the past I have often wondered if I have provided enough architecture for the software team to work to.  Conversely I always like to leave enough room to maneuver for the guys to do design for their own parts of the software, I would really hate it if I was working on a project where everything was defined and all I needed to do was "code in the blanks".

The idealist in me wants to provide just enough architecture to start work at all, and emergency design will do the rest.  I have found this is not how great software is made.  When everyone is left somewhat to their own devices, the code starts to lose coherence.  Everyone will code their own mini framework that will not interact well with other stories or allow extension for all requirements.  This is natural as everyone might not be aware of all requirements for the project.

The answer to this is pretty simple in practice, whenever two or more stories meet the following criteria you need some architecture:

1. Other code interacts with the product of a story.  
For example some kind of remote or local service or data.  In my current work we do a lot of inter-process communication.  This is really a technical detail, web services or in-process framework meets the same criteria.  Whatever it is, it needs some documented architecture.  The documentation part here is important, it should be simple to find look-up the exposed interfaces with arguments including valid values, errors etc.  This rule tends to reduce errors and confusion (more errors) occurring from not knowing about or not understanding .

2. Two or more stories are similar

For example, two kinds of message or input that could be handled in the same way or are similar enough to be categorised together.  Polymorphism and/or inversion of control can be used to have a central mechanism handle these in a reusable way.  This rule tends to reduce the overall amount of code and improve code quality. 

These two scenarios are sum up pretty much of every time where I had wished I had provided some architecture before work commenced

Thursday, 28 January 2010

Starting Listeners in the Correct State

A problem that I'm having with event listeners at the moment is making the listening object begin at a point in time in the correct state when it is really designed to build its state from the the events that are received while assuming a state to begin with.

For example, say you add a listener to an observable containing the state for a light switch, the listener should really know the state straight away but the event could be fired in 8 hours, or never. There are two ways I can see to fix this.

When adding the listener the listener gets the current state from the observable and updates itself.  This is fine but it does mean that the listener needs to know about the observable which adds a dependency so that the listening object is less reusable.  The Java property change framework is weakly typed, treating sources and values as objects anyway so you shouldn't really be expected to add this dependency.  Plus it makes the listener more difficult to test.

The observable holds a copy of the last event object it fired and when a listener is added fires all events to that listener.  This can give us even more problems.  Imagine firing an event with a complex or resource hungry value.  The complex object could have references to many other objects that would get garbage collected except that this stored event keeps them in memory.  An image is probably the best example of an object that you wouldn't like to keep in memory longer than necessary.  This really means that only primitive values, enums and other small immutables should be the values in change events.

These problems are really compounded for state machines where to get begin at the correct state the machine has to analyse system state in much the same way a conventional solution would need to.