Friday, August 21, 2009

Symptoms of Rotting Design

There are four primary symptoms that tell us that our designs are rotting. They are not
orthogonal, but are related to each other in ways that will become obvious. they are:
rigidity, fragility, immobility, and viscosity.
Rigidity. Rigidity is the tendency for software to be difficult to change, even in simple ways. Every change causes a cascade of subsequent changes in dependent modules. What begins as a simple two day change to one module grows into a multiweek marathon of change in module after module as the engineers chase the thread of the change through the application.
When software behaves this way, managers fear to allow engineers to fix non-critical
problems. This reluctance derives from the fact that they don’t know, with any reliability, when the engineers will be finished. If the managers turn the engineers loose on such problems, they may disappear for long periods of time. The software design begins to take on some characteristics of a roach motel -- engineers check in, but they don’t check out.
When the manager’s fears become so acute that they refuse to allow changes to software, official rigidity sets in. Thus, what starts as a design deficiency, winds up being adverse management policy.
Fragility. Closely related to rigidity is fragility. Fragility is the tendency of the software to break in many places every time it is changed. Often the breakage occurs in areas that have no conceptual relationship with the area that was changed. Such errors fill the hearts of managers with foreboding. Every time they authorize a fix, they fear that the software will break in some unexpected way.
As the fragility becomes worse, the probability of breakage increases with time,
asymptotically approaching 1. Such software is impossible to maintain. Every fix
makes it worse, introducing more problems than are solved. Such software causes managers and customers to suspect that the developers have lost control of their software. Distrust reigns, and credibility is lost.
Immobility. Immobility is the inability to reuse software from other projects or from parts of the same project. It often happens that one engineer will discover that he needs a module that is similar to one that another engineer wrote. However, it also often happens that the module in question has too much baggage that it depends upon. After much work, the engineers discover that the work and risk required to separate the desirable parts of the software from the undesirable parts are too great to tolerate. And so the software is simply rewritten instead of reused.
Viscosity. Viscosity comes in two forms: viscosity of the design, and viscosity of the environment. When faced with a change, engineers usually find more than one way to make the change. Some of the ways preserve the design, others do not (i.e. they are hacks.) When the design preserving methods are harder to employ than the hacks, then the viscosity of the design is high. It is easy to do the wrong thing, but hard to do the right thing.
Viscosity of environment comes about when the development environment is slow
and inefficient. For example, if compile times are very long, engineers will be tempted to make changes that don’t force large recompiles, even though those changes are not optiimal from a design point of view. If the source code control system requires hours to check in just a few files, then engineers will be tempted to make changes that require as few check-ins as possible, regardless of whether the design is preserved.

These four symptoms are the tell-tale signs of poor architecture. Any application that exhibits them is suffering from a design that is rotting from the inside out. But what causes that rot to take place?

Source: Robert C. Martin (http://www.objectmentor.com/)

How can we detect sofware rot before or while it is occuring? Under the motto "To prevent is better than to cure".
The problem is that software roth rarely shows on the short term. I like to compare it to building a house... you build the basement and you realise its not level but level enough for now since your scope is quite limited. When you start building the ground floor you notice that it the problem is becoming more eminent, if after a while you construct more and more floors you will notice that your apartment block will eventually collapse but by then its too late to do something about it.

Everybody knows this but how can we prevent this? I have seen this occur over and over again due to short term quick and dirty hacks and solutions because developers do nor succeed in managing expectations. The only thing you can be certain about in software is change! "It works for now" is imo the beginning of the end.

How can we prevent this? By applying the SOLID principles:
  • SRP: Single Reponsibility Principle
  • OCP: Open Closed Principle
  • LSP: Liskov Substitution Principle
  • ISP: Integration Segragation Principle
  • DIP: Dependency Inversion Principle

For more information on this I would recommend Robert C. Martin's Agile Principles, Patterns and Practices in C#