Appendix A: A Brief Overview of GoF Design Patterns
We all have unique thought processes. So, in the early days of software development, engineers faced a common problem—there was no standard to instruct them on how to design their applications. Each team followed its own style, and when a new member (experienced or inexperienced) joined an existing team, understanding the architecture was a gigantic task. Senior or experienced members of the team would need to explain the advantages of the existing architecture and why alternative designs were not considered. The experienced developer also would know how to reduce future efforts by simply reusing the concepts already in place. Design patterns address this kind of issue and provide a common platform for all developers. You can think of them as the recorded experience of experts in the field. Patterns were intended to be applied in object-oriented designs with the intention of reuse.
In 1994, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides published the book Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994). In this book, they introduced the concept of design patterns in software development. These authors became known as the Gang of Four. I refer to them as the GoF throughout this book. The GoF described 23 patterns that were developed by the common experiences of software developers over time. Nowadays, when a new member joins a development team, the developer is expected to know about the design patterns, and then the developer learns about the existing architecture. This approach allows a developer to actively participate in the development process within a short period of time.
The first concept of a real-life design pattern came from the building architect Christopher Alexander. During his lifetime, he discovered that many of the problems he faced were similar. So, he tried to address those issues with similar types of solutions.
Each pattern describes a problem, which 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.
—Christopher Alexander
The software engineering community started believing that though these patterns were described for buildings and towns, the same concepts can be applied to patterns in object-oriented design. So, they felt that we could substitute the original concepts of walls and doors with objects and interfaces. The common thing in both fields is that, at their cores, patterns are solutions to common problems.
It is important to note that the GoF discussed the original concepts of design patterns in the context of C++. But C# 1.0 was released in 2002, and then it went through various changes. It grew rapidly and secured its rank in the world’s top programming languages within a short time, and in today’s market, it is always in high demand. At the time of this writing, C# 8.0 is available with Visual Studio 2019. The concepts of design patterns are universal. The book is written in C#, but if you are familiar with any other popular programming languages such as Java, C++, and so on, you can relate because I primarily focus on the design patterns and not on the latest features of C#. I purposely chose simple examples to help you understand these concepts easily. Exercising these
fundamental concepts
of design patterns using C# always make you a better programmer and help you to reveal an upgraded version of you. The following are some important points to remember.
A design pattern describes a general reusable solution to software design problems. When developing a software application, you may encounter these problems frequently. The basic idea is that you can solve similar kinds of problems with similar kinds of solutions. And these solutions were tested over a long period of time.
Patterns provide you a template of how to solve a problem and can be used in many different situations. At the same time, they help you to get the best possible design much faster.
Patterns are descriptions of how to create objects and classes and customize them to solve a general design problem in a particular context.
The GoF discussed 23 design patterns. Each of these patterns focuses on object-oriented design. Each pattern can also describe the consequences and trade-offs of use. The GoF categorized these 23 patterns based on their purposes, as shown next.
- A.
Creational Patterns
These patterns abstract the instantiation process. You make the systems independent from how their objects are composed, created, and represented. In these patterns, you should have a basic concern: “Where should I place the
new keyword in my application?” This decision can determine the degree of coupling of your classes. The following five patterns belong in this category.
Singleton pattern
Prototype pattern
Builder pattern
Factory Method pattern
Abstract Factory pattern
- B.
Structural Patterns
Here you focus on how classes and objects can be composed to form a relatively large structure. They generally use inheritance or composition to group different interfaces or implementations. Your choice of composition over inheritance (and vice versa) can affect the flexibility of your software. The following seven patterns fall into this category.
Proxy pattern
Decorator pattern
Adapter pattern
Facade pattern
Flyweight pattern
Composite pattern
Bridge pattern
- C.
Behavioral Patterns
Here you concentrate on algorithms and the assignment of responsibilities among objects. You also need to focus on the communication between them and how the objects are interconnected. The following 11 patterns fall into this category.
The GoF made another classification based on scope, namely whether the pattern primarily focuses on the classes or its objects. Class patterns deal with classes and subclasses. They use inheritance mechanisms, so, these are static and fixed at compile time. Object patterns deal with objects that can change at run time. So, object patterns are dynamic. Factory Method pattern, Interpreter pattern,and Template Method pattern can be classified as class patterns. Remaining patterns of the GoF can fall into object patterns. It is interesting to note that depending on the implementation,an Adapter pattern can fall in both category.
Q&A Session
A.1 What are the differences between class patterns
and object patterns
?
In general, class patterns focus on static relationships, but object patterns can focus on dynamic relationships. Class patterns focus on classes and subclasses, and object patterns focus on an object’s relationships.
Table
A-1 shows the summarized content that was discussed in the GoF’s famous book.
Table A-1
Class Patterns
vs Object Patterns
| Class Patterns | Object patterns |
---|
Creational
| Can defer object creation to its subclasses | Can defer object creation to another object |
Structural
| Focuses on the composition of classes (primarily uses the concept of inheritance) | Focuses on the composition of objects |
Behavioral
| Describes algorithms and execution flows; uses inheritance mechanism | Describes how different objects work together to complete a task |
A.2 Can I combine two or more patterns in an application?
Yes. In real-world scenarios, this type of activity is common.
A.3 Do these patterns depend on a particular programming language
?
Programming languages can play an important role. But the basic ideas are the same, patterns are just like templates, and they give you an idea in advance of how you can solve a problem. In this book, I primarily focused on object-oriented programming with the concept of reuse. But instead of any object-oriented programming language, suppose you have chosen some other language like C. In that case, you may need to think about the core object-oriented principles such as inheritance, polymorphism, encapsulation, abstraction, and so on, and how to implement them. So, the choice of language is always important because it may have some specialized features that can make your life easier.
A.4 Should I consider the common data structures
like arrays, linked lists also as different design patterns?
The GoF excludes those saying that they are not complex, domain-specific designs for an entire application or subsystem. They can be encoded in classes and reused as-is. So, they are not your concern in this book.
A.5 If no particular pattern is 100% suitable for my problem, how should I proceed?
An infinite number of problems cannot be solved with a finite number of patterns for sure. But if you know these common patterns and their trade-offs, you can pick a close match. Lastly, no one prevents you from using your own pattern for your own problem. But you must tackle the risk, and you need to think about your return on investment.
A.6 Do you have any general advice before I jump into the topics?
I always follow the footsteps of my seniors and teachers who are experts in this field. And here are some of their general suggestions.
Program to a supertype (Abstract class/Interface), not an implementation.
Prefer composition over inheritance in most cases.
Try to make a loosely coupled system.
Segregate the code that is likely to vary from the rest of your code.
Encapsulate what varies.
A.7 How do I use this book effectively?
This book focuses on commonly used design patterns. Most likely, you will face them very often in your everyday life. But the world is always changing, and new patterns keep evolving. To understand the necessity of a new pattern, you may also need to understand why an old/existing pattern is not enough to fulfill the requirement. You may consider this book as an attempt to make a solid foundation with design patterns so that you can move smoothly in your professional life, and you can adapt to the upcoming changes easily.