Consistency is a desirable property in a codebase due to the benefits in understandability and maintainability it provides. Application architecture assists here by providing a common template to which the system is constructed. Therefore the design of the architecture should be done in such a way that consistency may be effectively achieved. This does not mean that the benefits of consistency should imply that consistency must be enforced universally and in all cases. There are a number of cases where managed inconsistency brings greater benefit to the system.

Some systems will have highly disparate elements where there is no single architecture that will optimally address all the requirements. Indeed it may be that the optimal architecture* for the majority of the system will not allow some of the requirements to be met. If absolute consistency is mandated then a solution that is less effective (in terms of maintainability, flexibility, performance and other relevant criteria) may need to be selected to meet all the requirements. Where the requirements driving this choice represent a relatively small subset of the overall requirements we get a situation where a relatively large cost is imposed on all requirements to meet the needs of a few. The costs of such overhead can easily exceed the costs of having an exception to the standard application architecture to handle the special cases.

What is desirable here is having a manageable (preferably low single digit) number of designs for the different elements. This allows elements of the system to be non-standard in a standardised fashion. Although a greater cognitive overhead than having a single universal design this does not represent a huge or unmanageable set of complexities and the benefits to the implementation of the system generally outweigh these costs.

The other primary instance where inconsistency may be beneficial is when an improvement to the architecture is identified. Generally it is not justifiable to apply such an improvement to the entire system at once as this will provide little immediate benefit and caries significant risks and costs. In these cases a staged rollout of the improvements is preferable. New code and that which is being modified can have the new design applied, whereas code that is relatively stable can be left alone.

I've experienced cases where an argument is made that improvements to the design should not be performed because it would make the system inconsistent (these arguments have prompted this post). This argument is not always invalid. There are certainly cases where the scope of a change makes it inappropriate, such as when stabilising a system in preparation for a release. In general development outside these cases I don't feel this to be a compelling argument. It is essentially arguing that the system may never be improved simply because the improvement would not be applied immediately across the entire system.

What is required when applying a design change in this fashion is some management of the changes. Failure to do so will lead to a case where the system is scattered with multiple "improved" designs across its components and the corresponding problems with maintenance this can cause. This may involve such activities as periodically applying design improvements to all or parts of the code that have not otherwise been upgraded in order to improve the system consistency.

In summary:

  • Consistency is generally a good thing, but it is not the only thing
  • Inconsistency may be supported and beneficial where it is properly justified and managed
  • The alternatives to allowing inconsistency are often stagnation or a poorly fit design both of which can be very costly over the life of the system

* Optimal here being what the architect(s) consider to be the best architecture they may develop with their available resources rather than a measure against some mythical arbitrary scale of ideal architectures.