In the last post, I described the business drivers that are used in software architectures. But what exactly makes the architecture good? There are 4 main things which need to be considered:
- Conceptual Integrity
- Low Coupling
- High Cohesion
- Feasibility / Buildability
These make sense most of the time, but not always
This problem is usually associated with feature creep. Adding new features to software may cause a mess, so how do you decide which features to add and which not. Partially this may be driven by user requirements i.e. they really must have this feature otherwise software is useless. However, very frequently an addition of a new feature may also cause a mayhem in architecture. In those cases, the system architect may need to explain the predicament to the client. In the Mythical Man Month, Brooks argues that is is better to omit features and improvements for the sake of having a system reflecting a single set of principles and ideas. Therefore, it is usually important to use consistent approach. It makes easier to change projects as well as take over somebody's else code, because you understand what was done and why.
It may even be possible to arrive at a point, where one does not follow the architecture. For example, for performance benefit one may decide to stray away from the architectural design. This may result in loosing the architecture very quickly because as soon as you let one person not follow the architecture it all falls apart. On the other hand, you don't want to 'religiously' follow the architecture because that in turn can have consequences (usually performance). Architecture is neither authoritarian nor libertarian, it should be a mix of both.
Coupling and Cohesion
We usually say that we want to be able minimize coupling between modules and increase cohesion. A change in one object should affect the changes in another making the solution more modifiable. A classic example, if the Active Record design pattern. It is based on the idea that every entity is responsible for retrieving, saving, updating and deleting itself from the database. This way the main program doesn't have to be aware of the database, all it does it talks to the entities. The problem occurs when we want to have a list of those objects (or a combinations of those object) or even transactions. It all may be problematic, it would almost certainly a have a hit on performance. Another problem is associated with functional integration because it may be possible that we want the cruse control in the car talking directly to the engine. Cohesion is the 'togetherness' if any particular modules.
Feasibility and Buildability
This is associated with the tools and 'materials' available to build the solution. The tools may include the availability of compilers and debuggers as well as do we have expertise to build this software within the organization? Compilers still move through versions, do you change or not? What do you base this decision on? It is possible that some of the bugs in the compilers have been fixed, but have new been introduced? The 'materials' usually refer to programming languages and the associated platforms. Things like support for modularisation or library support. Is using Microsoft Access as our database, is it possible to provide remote retrieval mechanisms?
We come up with this fantastic and great architecture which seems to do all the things we want.
Is it possible to build?