Avoiding Evolutionary Complexity
Quite often, organizations developing products in a specific vertical market start out with the intent to produce a system that cleanly meets the needs of an entire customer base. Over time, however, they find that subtle nuances make each client unique.
Whether it involves different internal business processes, interfaces with different external systems, or just different user preferences, it often appears impossible to provide a one-size-fits-all solution in a specific niche.
Faced with growing variety of client needs, what happens next is a key point in product evolution. In the worst case, some companies jealously guard their rigid functionality and underlying implied business processes, constraining their clients and often losing business along the way. Other organizations opt to provide features that add to the flexibility of the system from the user perspective. In turn, this dramatically increases the complexity of the system for the development team.
As more options are made available to the end user in an uncoordinated fashion, the system will often reach a point at which the development team cannot anticipate all possible configurations, much less validate them all. As one organization put it, "Our system is so flexible we cannot possibly test it." Unfortunately, the results of that untestability have been readily apparent in the field, making them a candidate for the software equivalent of the Darwin Awards.
A more mature approach would be to acknowledge up front that there will be variability in user demands, and to design in the capability to manage this appropriately. With proper design, the complexity of permutations can be adequately managed. Focus on managed compatibility of the combinations and their interactions to avoid the possibility of unanticipated results at the client site. With these capabilities designed into the system, tests can then be devised and an associated test infrastructure, developed as required, can be used to thoroughly validate allowable permutations and confirm that the system correctly denies incompatible combinations. Any system deemed to be untestable to a point where it is a challenge to deploy has not been properly designed.
Indeed, for those systems that have already evolved to the point of being difficult to deploy and maintain, it can be prudent to take a step back and architect flexibility into the system properly. With the lengthy implementation phase (often a thinly veiled name for the phase of frantic struggle to make it fit at the client site) and costly maintenance phase taken into account, everyone benefits from a system that was properly designed to accommodate specific client needs in the first place.