Design as Structure

The main quality associated with a good design is modifiability: How easy it is to change the code. Modifiability can be measured in terms the propagation and locality of changes. When it is necessary to modify a module whether it is possible to keep all the changes confined to the module under change or it is also necessary to modify the modules that depend on it.

Locality of change is a quality that is required because the human brain is good at perceiving a problem that is located in a single place but it makes a lot of errors if it needs perceive the changes to be done in several places. In other words, it is easier to change one hundred lines of code inside a single class than one line of code in one hundred different classes.

Although there are several formulations of the principles behind a good design, a design that promotes the locality of changes, reducing the propagation of modifications, they can be summarized into two principles: high cohesion and low coupling.

The high cohesion principle states that the code that fulfils the same responsibility should be in the same place. For instance, all the methods in a class should manipulate the same data. The cohesiveness of a design entity ensures that when it is necessary to change its responsibility all the change occur inside the entity, promoting locality of change and reducing propagation.

The low coupling principle states that the dependencies between design entities should be weak, meaning that they confine the propagation of changes. Low coupling is usually achieved through interfaces which encapsulate the internals of the design element. However, low coupling depends on the quality of that interface: How effectively the interface provides an abstraction that fulfils the needs of their clients and hide the specificities of the design entity.

Low coupling and high cohesion are strongly interrelated principles and they cannot be used in isolation, they are the two faces of the same coin.

The design entities are called generically modules and they have an interface. For instance, in the Java language, a module can be a class or a package. Note that in Java the interface of a package is blurred, it is the sum of the interfaces of the classes and packages it contains.

Locality of change is a quality of the code that human work on that not necessarily of the final code. For instance aspect-oriented programming promotes the modularization of aspects that are intertwined in the final code. Developers interact with the code at the aspect level and code generation tools generate code that do not follow the principles of good design.