Today, employers want a programmer who knows more than just code. Anybody can watch some tutorials and learn how to program in C++ or another language. However, being a good programmer is just one component of being a good engineer. Companies seeking software engineers want team members who understand the process and architecture of the design and engineering process. This guide will help you ace any interview questions about the Gang of Four design patterns in C++ you might encounter.
What is the Gang of Four?
The Gang of Four design patterns (GoF) are a collection of design patterns in object-oriented programming proposed by the so-called “Gang of Four,” the authors of the seminal programming text Design Patterns. These patterns had an extreme influence on the field object-oriented programming as it matured in the 1990s. The Gang of Four design patterns emphasizes elegant solutions that use inheritance and encapsulation instead of hard-coding.
Gang of Four Design Patterns: The Complete List
There are three major types of GoF design patterns: creational, structural, and behavioral. Creational GoF design patterns involve instantiating new objects while structural patterns deal with helping different parts of the program fit in and work together better. Behavioral patterns, on the other hand, help different components of the system communicate with each other.
Creational Gang of Four Design Patterns
Creational Gang of Four design patterns often allow you to create new objects by means of inheritance. This makes it possible to create the object without needing a specific class. This has the advantage of allowing sub-classes to create the derivation. Through this approach, OOP is more flexible and saves unnecessary duplication of code.
The factory pattern is one of the most common GoF patterns. The idea is to separate the creation of an object from the client by using an interface. You create a factory to generate an object using the desired concrete classes.
Abstract Factory Pattern
An abstract Factory pattern organizes these objects according to theme by encapsulating these factories without using concrete classes. For example, LegalFormCreator might have interfaces for CreateLease() and CreateAddendums(). They would be used by derived classes such as CommercialLease() and ResidentialLease(), without needing access to the original specific version.
The builder pattern is used to separate construction from representation. In this pattern, construction is delegated to a builder object. The builder is a good example of encapsulation and loose coupling that are the hallmarks of OOP.
Object Pool Pattern
The object pool pattern recycle objects that the system is not using. This pattern is called a pool because you initialize the objects you want to use, keep them, and re-use them, rather than destroy them.
A prototype pattern is a pattern that uses an object to create a new object. This method is employed to save resources as compared with creating a real new object. It is essentially a form of the Factory Pattern that uses a clone() method.
The singleton pattern is the basic design pattern where only a single instance of an object of a class can exist. This is commonly used when such an object is necessary for use throughout the system.
Other recommended reads: If you are interested in other C++ interview questions, we also recommend reading our collection of CPP interview questions as well as our answer to the question how to use the virtual destructor in C++.
Structural Gang of Four Design Patterns
Structural Gang of Four design patterns focus on the relationship between the different parts of the program. The idea is to see how these classes and objects fit in and work together. They tend to simplify the overall functioning of the system.
The adapter pattern converts interfaces into the appropriate class for clients. This makes it possible for classes to work together despite having different interfaces. Adapters are a good example of the GoF preference for interfaces over implementations in OOP.
A bridge makes it possible to vary the implementation of an object from its interface. By separating the abstraction from implementation, the implementation can be changed. This pattern is particularly useful for search functions, for example.
Composite patterns allow each object to function with the same interface. This allows clients to treat objects and their compositions the same way. It is useful for situations in which objects are almost the same and are being treated in the same way by clients.
Decorators are used to extend functionality by using decorator classes instead of having to create an inordinate number of sub-classes. Instead, we can use inheritance to modify behavior. Decorator functions are another example of using encapsulation to enhance flexibility using GoF design patterns. Decorator patterns extend functionality by using decorator classes instead of having to create an inordinate number of sub-classes. Instead, we can use inheritance to modify behavior.
The facade pattern is a GoF pattern where a single class stands in for a whole subsystem. This simplifies the entire structure of the system by creating an interface that is easier to use. In a sense, it is kind of decorator pattern applied to a whole class. Facade patterns are often used to test extremely complex systems.
The flyweight pattern allows for recycling objects for common tasks. We can use the same object in several contexts. They use the same principle as object pool patterns and use inheritance to keep from creating and destroying objects.
Behavioral Gang of Four Design Patterns
In the GoF paradigm, behavioral GoF patterns have to do with the communication aspects of systems. The word “communication” suggests that objects are “talking to each other,” but the word “communication” in this case has a broad meaning. Behavioral patterns involve abstracting the action from the object, using inheritance to “copy” the object without changing the classes. This allows the programmer to change behavior without altering the way the interface works.
Chain of Responsibilities
A chain of responsibilities GoF pattern is a pattern that involves passing a request in an object chain. The request can be passed along the chain and used by different handlers. The handlers make use of their type of command and then pass the rest of them on to continue the chain.
A command pattern is a pattern where an action is encapsulated. This allows us to hold the request and use it at any time. This is a similar idea to object pool and flyweight patterns.
An interpreter pattern is a pattern in which you use your own “little language,” or grammar, to solve a particular problem. In a general sense, wherever you use the composite pattern, you must also use the interpreter pattern. That’s because you are distributing function over a class hierarchy.
An iterator pattern is simply a pattern that allows for access to a sequence in a certain order. It uses encapsulation to avoid exposing classes when dealing with a container’s elements.
A mediator pattern involves encapsulation of object interaction, a basic OOP concept known as “loose coupling.” This is similar to many of the other patterns that allow us to use objects without needing to grant access to classes.
Memento patterns are those store an object state so that we can retrieve it in exactly the same form in the future. The classic example of a memento pattern is the pseudo-random number generator. After initializing it with a certain seed (the state), it always returns the same “random” number.
The observer pattern watches for any changes to a state of an object. Other relevant objects are plugged in and find out when any change occurs.
A state pattern is when there is a change in an objects behavior that corresponds to some change in state. This is a way of “changing an object’s class,” without really doing so.
The strategy pattern is essentially a class that specifies some algorithm in the system. This allows you to implement different strategies based on different situations. Strategy patterns are encapsulations of algorithms.
The template pattern involves sending certain parts of an algorithm to sub-classes, where changes made via inheritance without affecting the main algorithm. This is the same idea as a decorator pattern.
The visitor is somewhat similar to a state pattern, but specifically referring to or adding some operation to a class without actually altering it. Like a state or template pattern, a visitor pattern uses inheritance to “change” an object without affecting its classes.
Since the 1994 publication of Design Patterns, countless numbers of programmers have studied and mastered the principles of effective OOP design. Although much has changed in the last twenty years in terms of technology and the programming languages we use on a daily basis, we can still easily observe the basic concepts in this excellent book as we go through books about coding.
By learning these patterns and keeping in mind that GoF patterns involve using inheritance to separate clients from classes as much as possible, you will be in good shape for your interview. In short, applying GoF principles simply means good object-oriented programming.