Design patterns are solutions to frequently occurring real-life problems in software design. They can also be considered customizable templates that can meet the requirements of a particular design problem.
Advantages of design patterns
The following are some of the advantages of using design patterns:
- They provide correct and efficient solutions since various experienced programmers have derived and optimized them over time.
- They are generic templates that can be modified to solve different problems.
- They can provide a clean and elegant solution to a large problem by avoiding repetition in the code.
- They provide a template upon which the developers can build. This allows developers to spend less time on code structure and more on the overall quality of the solution.
Consequences of unfamiliarity with the design patterns
While there are many advantages of using design patterns, it is essential to understand the depths of design patterns entirely since unfamiliarity might cause the following issues:
- Design patterns can complicate the application's architecture if they are managed poorly.
- Developers unfamiliar with them might need clarification on why particular patterns are used.
Creational design patterns
These patterns provide a mechanism for creating objects in a specific situation without revealing the creation method. The standard approach for creating an object might lead to complexities in the design of a project. These patterns allow flexibility in deciding which objects need to be made for a specific use case by providing control over the creation process.
When to use creational design patterns?
Creational Design Patterns | When to use |
---|---|
Factory pattern | - When the type of objects required cannot be anticipated beforehand. - When multiple objects that share similar characteristics need to be created. - When you want to generalize the object instantiation process, since the object set up is complex in nature. |
Constructor pattern | - You can use it when you want to create multiple instances of the same template, since the instances can share methods but can still be different. - It can be helpful in the Libraries and Plugins design. |
Singleton pattern | The Singleton pattern is mainly used when we want a single object to coordinate actions across a system. - Services can be singleton since they store the state and configuration and provide resource access. Therefore, having a single service instance in an application makes sense. - Databases such as MongoDB utilize the Singleton pattern regarding database connections. - Configurations are used if an object has a specific configuration, and we donât need a new instance every time that configuration object is required. |
Builder pattern | - This design pattern can be used when building complex object-creation apps. It can help you hide the construction process of these objects. - A good example would be a DOM, where we might need to create numerous nodes and attributes. The construction process can get messy if we build a complex DOM object. In cases like these, the Builder pattern can be used. - Spark Connection |
Prototype pattern | - To eliminate the overhead of initializing an object. - We want the system to be independent of how the products are created. - When creating objects from a database whose values are copied to the cloned object. |
Abstract pattern | - Applications requiring the reuse or sharing of objects. - Applications with complex logic because they have multiple families of related objects that need to be used together. - When we require object caching. - When the object creation process is to be shielded from the client. |
Structural design patterns
These patterns are concerned with class/object composition and relationships between objects. They let us add new functionalities to objects so that restructuring some parts of the system does not affect the rest; hence, when some parts of the structure change, the entire system does not need to change.
When to use structural patterns?
Let's see when we can use the structural patterns discussed above:
Structural Design Patterns | When to Use |
---|---|
Decorator | - To modify or extend the functionality of an object without changing its base code. - To implement additional functionalities of similar objects instead of reusing the same code. |
Facade | - To simplify a clientâs interaction with a system by hiding the underlying complex code. - To interact with the methods present in a library without knowing the processing that happens in the background. |
Adapter | - To enable old APIs to work with new refactored ones. - To allow an object to cooperate with a class that has an incompatible interface. - To reuse the existing functionality of classes. |
Bridge | - To extend a class in several independent dimensions. - To change the implementation at run time. - To share the implementation between objects. |
Composite | - To allow the reuse of objects without worrying about their compatibility. - To develop a scalable application that uses plenty of objects. - To create a tree-like hierarchy of objects. |
Flyweight | - To share a list of immutable strings across the application. - To prevent load time as it allows caching. |
Proxy | - To reduce the workload on the target object. |
Behavioral design patterns
These patterns are concerned with communication between dissimilar objects in a system. They streamline communication and ensure that the information is synchronized between such objects.
When to use behavioral design patterns?
Behavioral Design Patterns | When to use |
---|---|
Chain of Responsibility pattern |
- It can be used where a program is written to handle various requests in different ways without knowing the sequence and type of requests beforehand. - It can be used in the process of event bubbling in the DOM, where the event propagates through the nested elements, one of which may choose to handle the event. |
Command pattern | - It can be used to queue and execute requests at different times. - It can be used to perform operations such as âresetâ or âundoâ. - It can be used to keep a history of requests made. |
Iterator pattern | - This pattern can be used when dealing with problems explicitly related to iteration, for designing flexible looping constructs and accessing elements from a complex collection without knowing the underlying representation. - It can be used to implement a generic iterator that traverses any collection independent of its type efficiently. |
Mediator pattern | - It can be used to avoid the tight coupling of objects in a system with a lot of objects. - It can be used to improve code readability. - It can be used to make code easier to maintain. |
Observer pattern | - It can be used to improve code management by breaking down large applications into a system of loosely-coupled objects. - It can be used to improve communication between different parts of the application. - It can be used to create a one-to-many dependency between objects that are loosely coupled. |
Visitor pattern | - It can be used to perform similar operations on different objects of a data structure. - It can be used to perform specific operations on different objects in the data structure. - It can be used to add extensibility to libraries or frameworks. |
Architectural design patterns
These patterns are used to solve architectural problems within a given context in software architecture.
As discussed above, design patterns play a significant role in the structuring of an application and are of great use to a developer. In the next few lessons, we will discuss the most common design patterns so that you can confidently answer any questions related to them in an interview and be able to implement them at your job.
Pattern name | Intent | Motivation | Structure | Consequences | Implementation |
---|---|---|---|---|---|
In interview
These are the following steps, which can be followed in the interview:
- Identify the requirements
- How good are you at collecting requirements?
- Can you effectively scope down the problem?
- Can you produce a design based on your requirements within the 30â45 minutes given to you?
- Model the problem with system, actor, and use cases.
What not to do in an interview
Here are a few things that you should avoid in an object-oriented design interview:
- Donât start building without a plan.
- Donât work in silence. It is encouraged to think out loud during the interview.
- Donât code the system's implementation unless specifically asked. You only need to define your classes and methods.
- If you donât know something, donât pretend to know it.