Everything should be made as simple as possible, but not simpler.
Emergent Design Abstract
The essence of incremental design is that we start with what we know, create an initial design, and then extend the design as we learn more. This is also called “emergent design” as the design emerges over time. XP implements incremental design through a triad of coding standards, simple design and refactoring.
Originally called ‘Simple Design’ in XP, the word ‘simple’ has confounded most people. The intention is that the code be easy to maintain which requires not being more complex than necessary. Hence, we label this set of practices by their intention which is easier to understand.
The essence of incremental design is that one never adds complexity that is not needed. Our mantra is to have our code be of as high quality as possible, but not more than we need. Simple design does not mean no design, but rather the right level of design. Design patterns are often misunderstood as being heavy design. However, patterns are more about the thought process behind the defined patterns than the patterns themselves. An essential coding practice to enable simple design that can easily evolve is to separate use from construction.
Design patterns are often thought of as “solutions to recurring problems in a context.” However, they are actually more than that. They are a thought process. Patterns are about helping us resolve forces in our problem domain, about seeing these forces. Using patterns still requires us to think – in fact, maybe more so. However, knowing patterns helps us know what we should be thinking about. Patterns are useful because they give us a common language as well as providing us with approaches to solve our problems.
Refactoring is a critical part of Agile coding and design. “Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs. In essence when you refactor you are improving the design of the code after it has been written.” There are actually two situations where refactoring is used – cleaning up messy code and extending a design with quality code.
Use refactoring to clean up messy code. Be clear this is not an excuse to have messy code but rather reflects that fact that after programming one often has insights on how to make code that was just written better. The intention of refactoring in this situation is to always have quality code.
However, even when there is quality code present, refactoring is often needed. This is when a requirement requires a design change. In other words, the quality of the code you have may be good. But now a new requirement shows up that requires a different design. Since we’ve been attending to simple design, it is likely our current design will not handle this new requirement – if it did, our design was not as simple as it could be. The question now is, how do we extend our system?
Refactoring your designs. Given we have simple designs that must evolve, we must learn a way to refactor our designs in a disciplined way. A method for this, called Refactoring to the Open-Closed provides a way. Essentially, it says to first refactor the design to the more complex design now needed. After this is done, add the new functionality required by the new requirement.
 Fowler, Martin. Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.
 Bain, Scott. Emergent Design: The Evolutionary Nature of Professional Software Development. Addison-Wesley, 2012.
Last update: 15 January, 2013
© 2010-2013 Leffingwell, LLC. All rights reserved.