The open source industry has done very well achieving this with infrastructural frameworks such as Spring and Hibernate.
However there are not many success stories when we look at business applications and most companies end up with a series of branches of their software for different clients.
These are normally created by taking the closest implementation of an applications in respect to the new customer's requirements and branching it of.
After not very long the two branches will be too different to each other to even attempt to maintain them as one product. Any good intentions the company had at the start of the project to merge the two branches back together after the new client went live are generally not only quickly forgotten but not even mentioned ever again.
Next time then the company does a rewrite of this business application or creates a brand new product one of the first requirements to surface will be to make this particular application reusable (same as it was intended last time around).
The general approach to this is that a set of business analyst will try to analyse any requirements that their existing clients or future clients has or is likely to have in the future and to create a design that will contain all of these.
If you are lucky this process might even entail looking at the existing applications and to try to find out what went wrong. This is however the exception rather than the norm as such an exercise holds the risk to embarrass the people who were in charge of the last failure to achieve it and who are likely to be now the people who would be in charge of instigating such an exercise ...
So far so good and depending on the experience of the analysts we might end up with a decent design. It's from here on that things will start to go downhill:
First of all time lines will get tight. As the pressure of the delivery of the first implementation to the first customer is growing the tendency to create compromises (obviously only temporary compromises ...) grows as well. These compromises will be twofold:
- Functionality that is not initially required or was just included to please potential future customers will be 'postponed'.
- Mechanisms intended to make future enhancements easier will be replaced by 'temporary' short cuts
The new customer's requirements will not only include some of the functionality we dropped but most likely will also entail new functionality no one had thought of in the initial analysis phase.
To make things worse the initial customer, having gone live now, will discover all the bugs which were missed during the acceptance phase and the will discover another set of functionality required that crystallised as they started to use the application in earnest.
These bugs and enhancements will be very urgent and the team is likely to chase it's own tail to achieve them. One thing the team will most likely not want to do, is risk any stability there is by introducing the set of requirements for the new client at the same time. So we branch ...
So what are the lessons:
- We will never analyse all future requirements upfront
- We most likely will only implement the functionality really required
- We are unlikely to risk a live implementation to add functionality required by another customer
One of the reasons it is as successful as it is because the individual building blocks are very small and generic. You do not have a single building block that resembles a whole house or car but many small ones with which you can build either or something totally different.
This does not mean however that you can't reuse the blueprints of the houses you have built. You can now rapidly rebuild any of these if someone else wants the same house (the themed Lego kit). But even when you do this you are able to change whichever detail you want for this new house. Most of these kits have instructions for several designs included.
The other feature making Lego as reusable as it is, comes from it's composition model.
You will not need any glue or cement to build your structures. At the same time the resulting structure will look as if is was one rather than many pieces. You can take any of the structures however and combine those seamlessly again.
Lastly, due to the lack of the glue you are also able to remove some of the blocks again at a later stage and replace them with some others or reuse them for a different construct.
I know we are not in the business of supplying toys.
The lesson to learn however is that as long as we try to create large reusable blocks which will fit all we will fail.
And if we do not create a mechanism for our blocks to seamlessly integrate whilst allowing for these integrations to be changeable we will also fail.
I will try to detail in my comming blogs some of the mechanisms which we can use to build our applications like Lego constructs, e.g. how we can use small generic building blocks, combine them seamlessly and create large applications out of it.