Introduction to system design patterns
Tags: systemdesign, designpatterns, softwareengineering, oop
Published: 2024-03-10 23:24:06


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7an8l7ygiqe5zqe4p9q8.png)

When designing software applications there are a set of recurring problems that one may do several times. These problems form a pattern for most complex and robust systems and a set of design patterns were developed. One of the main reasons why computer science researchers began to recognize design patterns was to satisfy the need for good simple and reusable solutions. These are known as the software or system design patterns.

## So what exactly are Software design patterns
In simple terms, design patterns are recurring solutions to design problems you see over and over. They constitute a set of rules (or perhaps guidelines ) describing how to accomplish certain tasks in the realm of software development.
Design patterns exist on many levels, from very low-level specific solutions to broadly generalized system architectures and hundreds of these were developed through the years to attack these problems. However, only a few of them are utilized in today's system designs

## Types of Design Patterns
Design patterns can be grouped into three groups which are creational, structural, and behavioral patterns which all talk about the same thing at the core that is object inheritance and containement in Object Oriented Programming (OOP). I will explain how to choose the best pattern in the next session.

## 1. Creational patterns

## A. Singleton
Ensure a class only has one instance, and provide a global point of access to it.

**Motivation:**
It’s important for some classes to have exactly one instance. How do we ensure that a class has only one instance and that the instance is easily accessible? A global
variable makes an object accessible, but it doesn’t keep you from instantiating multiple objects.
A better solution is to make the class itself responsible for keeping track of its sole instance. The class
can ensure that no other instance can be created (by intercepting requests to create new objects), and it
can provide a way to access the instance. This is the Singleton pattern.

**Applicability:**
there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point.
when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a84cpahu2cz8p98wo2bn.png)

Some of the benefits of this pattern include:

1. Controlled access to the sole instance. Because the Singleton class encapsulates its sole instance, it can have strict control over how and when clients access it
2. Reduced name space. The Singleton pattern is an improvement over global variables. It avoids polluting the namespace with global variables that store sole instances.
3. Permits a variable number of instances
4. Permits refinement of operations and representations

## B. Prototype pattern

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. this in simple words means hiding the complexity of the object using a prototype

**Motivation**
Use the Prototype pattern when a system should be independent of how its products are created, composed, and represented; and
When the classes to instantiate are specified at run-time, for example, by dynamic loading; or
To avoid building a class hierarchy of factories that parallels the class hierarchy of products; or
When instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dy6s4fqht857qph54hu8.png)

## C. Builder pattern
Separate the construction of a complex object from its representation so that the same construction process can create different representations.

**Use the Builder pattern when**
The algorithm for creating a complex object should be independent of the parts that make up the object and how they’re assembled.
The construction process must allow different representations for the object that’s constructed.
To better explain, this means the Builder Pattern promotes algorithm independence, allowing for flexibility in the construction process, and enables the creation of objects with different representations without modifying the client code. It’s particularly beneficial when dealing with complex objects that have multiple optional components or configuration


## D. Abstract Factory Pattern ( aka Kit )
Provide an interface for creating families of related or dependent objects without specifying their concrete classes

Use the Abstract Factory pattern when
A system should be independent of how its products are created, composed, and represented.
A system should be configured with one of multiple families of products.
A family of related product objects is designed to be used together, and you need to enforce this constraint.
A you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnobg3e0mcdty06h7az1.png)
The Abstract Factory pattern has the following benefits and liabilities:
1. It isolates concrete classes
2. It promotes consistency among products.
3. It makes exchanging product families easy. The class of a concrete factory appears only once in an application — that is, where it’s instantiated. This makes it easy to change the concrete factory an application uses


## Factory Method Design Pattern (aka Virtual Contructor)
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

Use the Factory Method pattern when
a class can’t anticipate the class of objects it must create.
A class wants its subclasses to specify the objects it creates.
A classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate
This design pattern is applied when a class needs to delegate the responsibility of object creation to its subclasses, allowing for flexibility, extensibility, and localized knowledge of which helper subclass is the delegate. It’s a powerful design pattern for scenarios where the exact type of objects to be created is determined at runtime or when different subclasses need to specify the types of objects they create.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zgbifyk1mx96rd2ohfe.png)

## Let’s end here for today and next time we’ll talk about behavioural pattern and it’s containing patterns