Explain object-oriented design patterns Flashcards
1
Q
- What is a design pattern?
2. Why do we want to use design patterns? (*)
A
- Design patterns are a general solution to common problems that exist within the design of object orientated languages. They aren’t a one size fits all solution, and they’re far from always applicable/the best practice, but rather a template for how issues can be solved. They should be viewed as best-practices.
- As aforementioned, these patterns help solve common problems which developers deal with regularly. They are a template on how one should form modules, classes, methods, interfaces, and more. They have been created over time by experts, with far more experience than you (thus meaning you shouldn’t discount them). They also make it a lot easier for programmers to follow the previously mentioned principles.
2
Q
Template Method
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Behavioural Design Patterns
- The template method is a method in a (usually abstract) superclass, and defines the skeleton of an operation in terms of a number of high-level steps. In layman’s terms, it’s a general method which uses an abstract method that allows the subclasses to define the part of the method that differs.
- This pattern would be used when each subclass needs to use a method which does almost the same thing, though with a small difference between the subclasses.
- The Template method pattern uses, as aforementioned, an abstract method which subclasses can use to define specific (not shared) behavior. The superclass also contains a non-abstract method that uses the abstract one.
- Using this pattern, code-reuse is far more prevalent, reducing duplicate code. This not only boosts readability, but also makes the code less prone to bugs, and more expandable (solidifying the adherence to the OCP).
3
Q
Bridge
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Structural Design Patterns
- Holistically, this pattern dictates what an object is. Using this pattern, one can split the abstraction of an object from the implementation- which can be developed independently of each other.
- Simply put, a certain characteristic/dimension of an object is extracted into a separate abstraction with defined characteristics, allowing the object to decide which to use.
The bridge pattern is applicable when an object can possess one of multiple dimensions (characteristics which don’t overlap). - To apply this pattern, one needs two separate hierarchies. This is best visualised by the below example.
- This pattern allows one to change the classes in each hierarchy independently of the classes in the others. This simplifies code maintenance and minimises the risk of breaking existing code. Furthermore, it allows the code to depend on abstraction over implementation.
4
Q
Factory
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Creational Design Patterns
- The factory design pattern is amongst the most used patterns in OOP, owing to the fact that it provides one of the best ways to create objects. It does so without exposing the instantiation logic to the client, and refers to the newly created object through a common interface. It’s composed of factory methods.
- In other words, it’s used when one wants to hide the implementation (what constructors and specific classes should be used), and allows the subclasses to decide which class to instantiate.
- This pattern is applied by first defining a factory class, which consists of multiple factory methods. These factory methods, when called, create a specific predefined object. These objects are often returned as a collection (i.e, in a list, array, deque, etc).
- In addition to the advantages stated above, it solves the problem of creating objects without having to specify the exact class of object that will be created, allowing for looser coupling. Allows the client to more easily adhere to SoC & the SRP. Can also be linked to the OCP since new objects can be added easily.
5
Q
Chain of Responsibility (*)
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Behavioural Design Patterns
- Chain of Responsibility is a design pattern that lets you pass requests (to do a certain thing) along a chain of “handlers”. These handlers can do one of two things. One, they can perform checks to pass along a request until it reaches a singular handler responsible for that specific request. Alternatively, the request can be handled successively by each handler, with data being passed on from one handler to another.
- There are several cases where this pattern is applicable. It can be used when:
- One wants to decouple a request’s sender and receiver,
- When multiple objects are candidates for handling a request and one wants the program to determine the “correct” one at runtime,
- When one doesn’t want to specify handlers explicitly the code
- When one wants to issue a request to one of several objects without specifying the receiver explicitly. - This pattern requires a “client” to send a request, a “base handler” (which can be an interface) which receives and dispatches the request, and the “concrete handlers” (classes which contain the different ways to handle a request) which are chained together sequentially.
- Aside from the solutions to design problems listed in (2), this pattern allows the decoupling of classes (related to the SRP), and also strengthens the adherence to the OCP (since new handlers can be introduced without breaking existing code).
6
Q
Module
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Architectural Design Patterns
- Used to implement the concept of software modules, strongly linked to the SoC principle, and information hiding.
2. Our (the authors’) belief is that there isn’t a strict situation/way to implement this pattern, due to the vague definition of it (and the fact that some languages don’t support the creation of modules at all). In a sense, it comes down to semantics and if this is even a design pattern. One interpretation is that it's only a Module Pattern if there is a class which represents the “module” (i.e. a class that encompasses/’gathers’ behavior defined in several patterns).
- To implement this pattern, all code which works to solve a concern (common goal) should be grouped together in one module. Code which only needs to be accessed within a certain class should ideally be made private, meanwhile code which is used in multiple classes within the same module should be made protected, or private and then accessed and manipulated through getters and setters.
- Gives a clearer structure to the code and implements the SoC principle. Also used to implement information hiding, making code less susceptible to bugs, thus making troubleshooting less of a hassle. Making code more abstract also strengthens its adherence to the DIP.
7
Q
Strategy
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Behavioural Design Patterns
- Strategy is a pattern dictating that if a class has a responsibility to perform an algorithm which it can do in several different ways, these algorithms should be extracted into separate classes called strategies.
- As aforementioned, it’s applicable when there’s multiple ways to perform a single responsibility (specifically, an algorithm).
- The components used are a class (that handles what to do with a set algorithm), an interface which the different classes containing strategies implement and, obviously, the classes which contain the concrete strategies.
- Benefits include better SoC, dynamic switching during runtime, simplified code (with all that that entails), and stronger adherence to the OCP, as new algorithms/strategies can be added without modifying pre-existing code.
8
Q
Decorator (*)
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Structural Design Patterns
1- When applied, the Decorator pattern enables an object to be “decorated” (wrapped) by another object, thus adding, but not changing the base, functionality of the object.
- This design is applicable when one wishes to provide additional functionality to objects whilst keeping the class’ methods signature intact.
- To implement the Decorator pattern, one needs an interface containing the method which adds functionality, the base superclass for objects, an abstract decorator class that implements the object superclass (the abstract decorator also has an object of the superclass), and a concrete decorator class which defines the additional behaviors.
- This pattern allows to extend an object’s behavior without making a new subclass, to add or remove responsibilities from an object at runtime, combine several behaviors by wrapping a class in multiple decorators, and aids the application of the SRP.
9
Q
Observer
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Behavioural Design Patterns
- This design pattern is used when there is a one-to-many relationship between objects, such as when the modification of one object requires its several dependent objects to be notified automatically.
In other words, an object (named the subject) maintains a list of its dependents (called observers), and notifies them automatically of any state changes, usually by calling one of their methods. - The observer pattern can be applied to any scenario which has the above entailed “one-to-many relationship”. This pattern can be used, for example, in the MVC pattern, when changes to the position of an object require the object to be redrawn in a panel. Or, more broadly, when View needs to know of changes that have occurred in Model.
- In the observer-pattern, there must be an observer. This is an interface with one method, usually called update or something similar. Each of the components which implement this interface will then have an update method which can be called by other parts of the program, just by iterating through a collection of these components, by applying the DIP.
- There are two main advantages that one gains from applying this pattern, the first being a greater adherence to the OCP (since it’s easy to add more views), and the second being that there are fewer dependencies, since one only calls upon the abstraction, that being, the observer interface. This also means the code has lower coupling.
10
Q
Facade
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Structural Design Patterns
- A facade is an object that serves as a front-facing interface (not the object-oriented type of interface!), used to mask/hide more complex underlying or structural code. This pattern involves a single class, which provides simplified methods required by clients, and delegates calls to methods of existing system classes.
- The Facade pattern is applicable in one of two scenarios, those being:
- When one wishes to make a complex subsystem easier to use,
- When the dependencies on a subsystem should be minimized. - To implement the Facade pattern, one must employ a class (the facade), which delegates the client’s requests to the necessary class(es).
- This pattern improves the readability and usability of the code by masking interaction with more complex components, and serves as a launching point for a broader refactor of monolithic or tightly-coupled systems, in order to promote looser coupling.
11
Q
State
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Behavioural Design Patterns
- This pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
- State pattern is applicable when you want to use the same object but with different behavior. An example of this is an amphibious car, where its state can either be “onLand” or “onWater”, and subsequently it’s behavior is dictated by the aforementioned.
- An interface is needed (to define the states), and classes (to define the behavior of an object in these different states) that are delegated into the object. Finally, one also needs methods contained in the objects class, which call upon the methods defined in the state classes.
- This pattern reduces duplicate code (thus leading to easier readability & debugging). It also follows the SRP, since code related to particular states can be contained within separate classes, as well as OCP since new states can be introduced without changing existing state classes.
12
Q
Adapter
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Structural Design Patterns
- The Adapter pattern enables objects with incompatible interfaces to collaborate.
- This pattern is very useful in the event that one has two objects which have incompatible interfaces. For example, you can wrap an object that operates in meters and kilometers with an adapter that converts all of the data to imperial units, such as feet and miles. This is most commonly an issue arising from the re-use of previous code.
- . In order to apply this pattern, one must first define an interface which describes a protocol (i.e condition) that other classes must follow to be able to collaborate with the client code (i.e the class which will use the adapted object). Secondly, one must create an ‘adapter’ class which implements the client interface, while wrapping the service object. The adapter receives calls from the client, via the adapter interface, and translates them into calls to the wrapped service object in a format it can understand.
- The Adapter pattern allows for greater abeyance to the SRP, since one can separate the interface or data conversion code from the primary logic of the program. Secondly, it strengthens the code’s adherence to the OCP, since it can introduce new types of adapters into the program without breaking the existing client code.
13
Q
Model-View-Controller
- Describe design pattern X.
- In which situations can you use X?
- Which components are included in X?
- What design problems can we solve with the help of X? (*)
A
Architectural Design Patterns
- The MVC pattern is one that’s commonly used when creating user interfaces. It divides the code into three interconnected elements/modules.
Model is the part of the program responsible for the data, logic, and “rules” of the ui.
View is responsible for the “output”, that being a representation of information (such as what a player of a game sees).
Lastly, Controller can be seen as the “input”, such as key-bindings and buttons that trigger commands or events contained within the Model. - MVC is applicable in any situations where one needs a UI that has both a form of input and output which a user can interact with.
- See 1.
- The use of MVC aids the codes adherence to the high cohesion & low coupling principle, since the Model, View, and Controller work in their own area of responsibility to do one cohesive function. This also allows for a greater adherence to the SoC principle.