Design Patterns for Software Engineering
Design patterns are a relatively new concept in software engineering, and have their origins in civil engineering. Essentially they are a blueprint for solving a specific problem, allowing the benefits of an optimal solution to be carried forward to new implementations.
The application of design patterns to the domain of software engineering was first formalised in the book "Design Patterns: Elements of Reusable Object-Oriented Software" by Eric Gamma, Richard Helm, Ralph Johnson, and John Vlissides, in 1995. The book selected 23 patterns considered to be core to understanding the pattern approach in solving software engineering problems.
While this book also set out many principles, it did not make a general template for pattern use available to the wider audience. Subsequently, applying patterns has not yet itself become a pattern-driven exercise. Engineers are left to decide how best to use patterns in different applications.
Structure of Design Patterns
What is clear is that there needs to be structure into which patterns can be formulated; this allows for them to be largely self-documenting. Indeed, one of the principles of using design patterns is that they should be structured, allowing each one to be created from a template.
At the very least, a template should contain:
- Pattern name : short, but descriptive;
- Intent : the goal of the pattern;
- Motivation : example of a problem, and how this pattern will solve it;
- Applicability : uses for this pattern;
- Structure : diagrams of the patterns classes;
- Participants : the responsibilities of the classes in the pattern;
- Collaborations : interfaces between the participants;
- Consequences : any trade-offs and forces that exist within the pattern.
This list is adapted from that provided by the Design Patterns authors, and can be used as rigidly or as loosely as is required. Some aspects will prove not to add any useful value to the template, but are provided here in the interest of completeness.
We have also refrained from using the term 'classes and objects', as is common in discussions of design patterns, preferring to only use the term 'classes'. The reason for this is one of object oriented design preference – if a pattern needs to be defined in terms of objects, then a certain implementation decision has been made and forced upon future adopters of the specific pattern.
Application of Design Patterns in Software Engineering
One of the key benefits in using design patterns in software engineering is as a way to improve communication between designers, and, to a certain extent, between non-programmers and programmers. In other words, as a communication tool, patterns can prove invaluable.
In addition, by abstracting solutions to common software engineering problems, design patterns can be used again and again. Since they use a proven solution each time, reuse at the design level is very high. This improves the quality of resulting implementations beyond that which would be achievable using only object oriented techniques.
The application of design patterns in the real world must necessarily be carried out with reference to other principles already deployed. In other words, while they offer solutions to common software engineering problems, there is no added value in creating patterns for every part of a system under development.
Instead, they should be used in cases where the resulting implementation (or design) is likely to have a use in future projects. In essence, the best way to use design patterns in software engineering is in providing standard behaviours between highly specialised classes in a software system. The are not a design technique per se, in the way that other paradigms are.
The reasons for using design patterns are essentially parallel to those for using any object oriented techniques. Design patterns encourage reuse, without constraining implementations to a specific platform or language, and promote efficient use of design time. They can be seen as the design equivalent of modular or object oriented programming.
Their strengths, however, can also be seen as their weakness. By not being implementations, the programmer is still required to actually code them, and as such any errors in the interpretation will be translated into the final source code. This means that different programmers may end up with different implementations of the same pattern, possibly even with different behaviours.
When working with design patterns, it is therefore important to remember that they should be precise enough that there are no possible misinterpretations. Using a suitable high level definition language that can be shown to be correct will help to ensure this.