12 Emergence

Getting Clean via Emergent Design

Many of us feel that Kent Beck’s four rules of Simple Design1 are of significant help in creating well-designed software. According to Kent, a design is “simple” if it follows these rules:

  • Runs all the tests
  • Contains no duplication
  • Expresses the intent of the programmer
  • Minimizes the number of classes and methods

Simple Design Rule 1: Runs All the Tests

Systems that aren’t testable aren’t verifiable. Arguably, a system that cannot be verified should never be deployed. Fortunately, making our systems testable pushes us toward a design where our classes are small and single purpose. It’s just easier to test classes that conform to the SRP. Tight coupling makes it difficult to write tests. So, similarly, the more tests we write, the more we use principles like DIP and tools like dependency injection, interfaces, and abstraction to minimize coupling.

Simple Design Rules 2–4: Refactoring

Once we have tests, we are empowered to keep our code and classes clean. We do this by incrementally refactoring the code. For each few lines of code we add, we pause and reflect on the new design.
During this refactoring step, we can apply anything from the entire body of knowledge about good software design. This is also where we apply the final three rules of simple design: Eliminate duplication, ensure expressiveness, and minimize the number of classes and methods.

No Duplication

Duplication is the primary enemy of a well-designed system. It represents additional work, additional risk, and additional unnecessary complexity. Duplication manifests itself in many forms. Lines of code that look exactly alike are, of course, duplication. Lines of code that are similar can often be massaged to look even more alike so that they can be more easily refactored.
As we extract commonality at very tiny level, we start to recognize violations of SRP. So we might move a newly extracted method to another class. That elevates its visibility.
The TEMPLATE METHOD pattern is a common technique for removing higher-level duplication.

Expressive

The majority of the cost of a software project is in long-term maintenance. In order to minimize the potential for defects as we introduce change, it’s critical for us to be able to understand what a system does. Therefore, code should clearly express the intent of its author. The clearer the author can make the code, the less time others will have to spend understanding it.
You can express yourself by choosing good names, keeping your functions and classes small, and by using standard nomenclature.
Well-written unit tests are also expressive. A primary goal of tests is to act as documentation by example. Someone reading our tests should be able to get a quick understanding of what a class is all about.

Minimal Classes and Methods

Even concepts as fundamental as elimination of duplication, code expressiveness, and the SRP can be taken too far. In an effort to make our classes and methods small, we might create too many tiny classes and methods.
High class and method counts are sometimes the result of pointless dogmatism. Such dogma should be resisted and a more pragmatic approach adopted. Our goal is to keep our overall system small while we are also keeping our functions and classes small. Remember, however, that this rule is the lowest priority of the four rules of Simple Design.

Previous: 11 SystemsUp: ContentsNext: 13 Concurrency