In one of the Facebook groups I am member of there is currently a discussion going on how to deal with extensible design, especially how to prove to a client that a system meets its extensibility expectations.
Focus on extensibility is important but can also be a big hazard, in particular, when engineers overdo it. For example, consider the application of the Strategy pattern. Basically, applying the Strategy patterns implies some kind of uncertainty which algorithm actually should be used. If many Strategy pattern instances are used, this almost always means that the engineers have no clue in which direction the system should be extensible. Of course, the same holds for overuse of other extensibility patterns as well. Such systems become a nightmare for developers and users.
Thus, make clear with requirements engineering or customers what kind of extensibility they really need.
What needs to be extended:
- Should an algorithm be exchanged?
- Is it a whole subsystem or layer that is subject to change or extensibility?
- Is it a component that needs to be changed or extended?
When will it be extended?
- Now,
- Mandatory in the future,
- Optionally in the future?
Which binding time?
- source code,
- compile time,
- link time,
- runtime,
- maintenance time?
Who will be in charge of extending?
- operator,
- user,
- developer
You should only consider those extensions that are mandatory, none of the possible or optional ones that may or may not appear in the future.
In the beginning of software design introduce change scenarios as proposed by the book Software Architecture in Practice, 2nd edition (Bass, Clements, Kazman). Here you’ll learn how to describe modifiability scenarios using scenario diagrams and rating them using so-called utility trees.
You may also use design tactics diagrams that deal with how to implement the different kinds of extensibility mentioned above.
If you follow the principles of my Onion Model, then each architecture design step will only be driven by requirements and their priorities. This way, you can establish requirements traceability within your architectural design.
For extensibility and change scenarios, a Commonality/Variability analysis can be leveraged, especially when dealing with a wide variety of extensions such as in platform or software product line development.
In contrast to common believe extensibility or change is only applicable after you’ve designed those parts of your architecture that are subject to extension or change. You can either extend some functional entities or operational qualities such as scalability mechanisms. This implies that all extensibility and change design activities follow after functional and operational design and not before.
When opening your functional & operational design for extensions or change always use the Open/Close principle to prevent unwanted side effects.
To prove that a software architecture is extensible such as expected by the customer you got different means.
- An end-user or operator might like to see the implemented change scenarios and how they actually work in the implementation.
- Another engineer might like to see how the architecture and implementation support extensions.
- A requirements engineer may like to see the mapping from requirements to architecture decisions.
Modifiability aspects (e.g., extensibility and changeability) are much more difficult than they seem at first place. When the amount of extensibility is overwhelming, you’ll often find wizards or configuration automatisms to hide the mess underneath (which does not imply that wizards or configurators are indicators for bad design).
As Heraklitus once said: panta rhei – everything changes. Thus, be prepared!