Over the last five weeks, we’ve looked at the SOLID design principles. We all know that good design is fundamental for good systems. Design patterns are an essential part of the skill-set for OO designers and developers. So I’ve decided to cover the most important design patterns in the next few weeks.
Good design improves the long-term success of non-trivial software systems. We must deliver software that is maintainable, extensible, testable, and not unnecessarily complex. A good way to become a skilled designer is to study design patterns.
A design pattern is an elegant way to solve a re-occurring problem in the most general, flexible manner possible. Design patterns capture expert knowledge in a way that makes it easy for us to learn and to reuse code.
Origins of design patterns
The idea of designing with patterns didn’t start with software. It started with architecture and urban planning. In the 1970’s, an architect, Christopher Alexander, created a pattern language to help design better buildings and public spaces. He published the first book on patterns, A Pattern Language – Towns, Buildings, Constructions” in 1977. He defined a pattern as follows:
“Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”
Alexander was writing about patterns in buildings and towns. Object-oriented design patterns work the same way. OO patterns are just expressed using classes and interfaces instead of walls and doors.
Software Design Patterns
In the 1990s, the software community started researching software patterns. One of the most influential books on software patterns is the 1994 work “Design Patterns” by Gamma, Helm, Johnson and Vlissides. They are commonly known as the Gang of Four or GoF. The book is a catalogue of 23 patterns of how to design software systems.
At the core of a pattern is an elegant solution to a common problem in a specific context. They consist of interconnected classes that have been customised to solve the problem. The problem could be one we may have already seen, worked on or solved. Our solution probably won’t be as complete or elegant as one found in a pattern.
A design pattern captures the design experience of experienced programmers. Design patterns make it easier to reuse successful designs and architectures. They help choose design alternatives that make a system reusable. Once we are familiar with patterns, we can apply them immediately to problems without having to reinvent a solution.
Although they’re called design patterns, their use isn’t limited only to the design phase of a project. Patterns can often appear at the analysis or preliminary design phases.
Design patterns provide an explicit specification of class interactions and their underlying intent. Design patterns help us get a design “right” faster.
One of the goals of design patterns is to create flexibility and isolate changes in our code. By adding abstractions to our design, we can separate things that change from things that stay the same. This makes the code easier to maintain and simpler to understand.
Classification of design patterns
The GoF identified three types of patterns – creational, structural and behavioural.
- Creational patterns:
These patterns deal with the best way to create instances of objects. Our programs can be more flexible and reusable if we isolate the details of the creational process into a “creator” class. - Structural patterns:
These patterns describe how classes and objects can be combined to form larger structures. These patterns promote decoupling which minimises the effects of requirement changes. - Behavioural patterns:
These patterns are concerned with communication between objects, encapsulating processes and implementing algorithms.
Behavioural | Creational | Structural |
---|---|---|
Chain of Responsibility Command (Action) Interpreter Iterator (Cursor) Mediator Memento (Token) Observer State Strategy (Policy) Template Method Visitor |
Abstract Factory Builder Factory (Virtual Constructor) Prototype Singleton |
Adapter (Wrapper) Bridge (Handle/Body) Composite Decorator (Wrapper) Façade Flyweight Proxy (Surrogate) |
The 23 patterns in the GoF book aren’t the only design patterns. There are many more patterns. Remember that a pattern is specific to a context; as the context changes so will the patterns.
A word of warning about design patterns
It can be tempting to use a pattern just to use it, and not because there is a specific problem to be solved. When we use a pattern, we often have to create extra classes and associations. This can increase the complexity of the solution. So we should not apply a pattern unless there is a definite problem to solve. Design patterns can’t be copied out of the GoF book and dropped into code. Each use is unique and the pattern must be adapted to fit the context.
What’s next?
Next week we’ll start with the Singleton design pattern. It’s a rite of passage to examine it first, almost like writing our first “Hello, world!” program.