Among the main quality criteria (availability, modifiability, performance, security, testability and usability) modifiability is the most interesting one. This is due to the fact that modifiability is hard to measure, yet every stakeholder will implicitly expect it to some degree.
However, as it happens with the other quality criteria of a software system, modifiability comes at a price and has to be defined with the same amount of care and attention to detail as any of the other, more easily measurable criteria.
Our task as developers and architects is to make modifiability explicit again, and to produce architectures that reflect our modifiability requirements.
In order to better understand this, we should have a look at how changes affect a software system. The following questions can help to better understand the impact of changes to our systems:
- What can change?
Today we focus largely on changes to the functionality of a system, i.e. changed requirements. We have tools and methods for producing code that is easy to refactor in reaction to such a change. However modifiability goes further than that. What about changing programming languages, development stack, hosting provider or even operating system? Further, a change in the priority of any of the quality criteria can have severe impacts on the architecture of a system, and thus lead to changes in several layers.
- How likely is a change?
This is a hard question to answer in a generic way. Individually, however, educated guesses can be made. For example, you can decide to use library A for now, although library B is much better, but still in beta. So you decide to architect your solution to make library A easily replaceable by B later on. (which you do anyway don’t you? :-))
- When is the change made?
This is in fact one of the most interesting questions, because it’s reasoning reminded me that I should design my software systems with late-binding in mind. Let me explain. When discussing this most people think that a change to a software system comes in, is passed to a developer who then implements the change for the updated software to be deployed. However, by differentiating the phases in which a change can have an impact, we can create much more flexible systems. Here are common phases and their changeable artefacts:
Phase Changeable artefact development time source code compile time compiler switches build time linker switches, build configuration files, etc. runtime settings, environment variables, plugins, etc.
depending on the environment, you might have more or less phases, but you get the idea. What is important is that the later the phase affected by a change, the better. A change in source code will almost always be of higher cost and effort than a change of an environment variable at runtime.
- Who does the change?
The actor actually doing the change can also have an impact on the architecture of the system. Most people assume the actor is always a developer, who has got the task of introducing changes due to new/changed requirements. However, other actors might introduce changes too. An administrator could introduce a change by moving the system to another hosting solution or by installing it on another flavour of Linux, etc.
- What is the cost of the change?
In terms of costs, changes have two dimensions. One is, well, the change itself. The second is the cost of introducing a mechanism to deal with that change. Again it is the architect’s job to anticipate changes as good as possible in order to find a good relationship between the cost of the mechanism and the predicted impact of the change.
Dealing with the above questions we can help make modifiability explicit in our architectures again. Also we can create awareness about the cost of modifiability. Last but not least, we can document what parts of a system should be modifiable, to what extent and how the decision was made.