fbpx
August 12, 2022

Design Patterns in Programming

Design patterns in software designs

Design patterns in software designs

Design patterns are solutions to common problems that occur in software design. They are not specific to any one programming language or framework, but can be implemented in any language.

Some common design patterns include the Singleton, Observer, and Factory patterns. In this article we are going to learn more :

Momento Design Pattern

Type : Behavioral

The momento design pattern is a software design pattern that provides a way to capture the current state of an object and store it in a momento. The momento can then be used to restore the object to its previous state.

One example of the momento design pattern is undo functionality in a text editor. When the user makes a change to the text, the old state of the text is stored in a momento.

If the user decides to undo the change, the text editor can use the momento to restore the text to its previous state.

Another example of the momento design pattern is a game save feature.

When the player saves the game, the current state of the game is stored in a momento. If the player wants to continue the game at a later time, the game can be restored from the momento.

Observer Design Pattern

Type : Behavioral

The Observer design pattern is a software design pattern in which an object, called 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.

Examples of the Observer design pattern include the Model-View-Controller (MVC) framework, the Model-View-ViewModel (MVVM) framework, and the Publish-Subscribe pattern.

Chain of responsibility design pattern

Type : Behavioral

The chain of responsibility design pattern is a programming design pattern in which an object is passed along a chain of objects, with each object in the chain having the opportunity to handle the request or pass it along to the next object in the chain.

A common example of the chain of responsibility design pattern is an event handling system, in which an event is passed from object to object until it is finally handled.

Another example is a system of logging messages, in which each object in the chain has the opportunity to log the message or pass it along to the next object in the chain.

Command Design Pattern

Type : Behavioral

The command design pattern is a behavioral design pattern that encapsulates a request as an object, allowing for the parameterization of clients with different requests, and the queuing or logging of requests.

It also allows for the undoing of requests.

Some examples of the command design pattern in programming include the implementation of the undo functionality in many text editors, as well as the implementation of the redo functionality.

State Design Pattern

Type : Behavioral

The State pattern is a software design pattern that implements a state machine in an object-oriented way.

With the State pattern, a state machine is encapsulated as an object with each state represented by a derived class. This allows the states to be changed at runtime.

Examples of the State pattern can be found in many software applications.

For example, a text editor application may have different states for editing, selecting text, and printing. Each state would be represented by a derived class.

When the application changes state, the text editor object would change its behavior by calling the appropriate methods in the new state object.

Interpreter Design Pattern

Type : Behavioral

The interpreter design pattern is a type of design pattern that is used to define how a programming language interpreter works.

This pattern is used to define how a language interpreter works by providing a set of rules that are used to convert a source code into a machine code.

The interpreter design pattern is used to define how a language interpreter works by providing a set of rules that are used to convert a source code into a machine code.

Strategy Design Pattern

Type : Behavioral

The strategy design pattern is a behavioral software design pattern that enables an algorithm’s behavior to be selected at runtime.

The strategy pattern defines a family of algorithms, encapsulates each algorithm, and makes the algorithms interchangeable within that family.

For example, a sorting algorithm may be defined as a strategy that encapsulates the different sorting algorithms (such as quicksort, mergesort, heapsort, etc.), and makes them interchangeable.

The client of the sorting algorithm can then select which sorting algorithm to use at runtime, without having to change the code that uses the sorting algorithm.

Iterator Design Pattern

Type : Behavioral

Iterator design pattern is a design pattern in which an iterator is used to traverse a container and access the container’s elements.

Iterator design pattern is used in many places in Java API, such as:

  • Iterating over a Collection using an Iterator
  • Iterating over a Map using an Iterator
  • Iterating over the elements of an Array using an Iterator

There are two types of iterators:

  • Standard Iterators
  • Custom Iterators

Standard iterators are those that are provided by the Java API, such as the Iterator for Collections and the Iterator for Maps. Custom iterators are those that are created by the programmer.

Example of a standard iterator:


Iterator<Integer> itr = myList.iterator();
while(itr.hasNext()) {
   Integer element = itr.next();
   // do something with element
}

Example of a custom iterator:

MyCustomIterator<Integer> itr = new MyCustomIterator<>(myList);
while(itr.hasNext()) {
   Integer element = itr.next();
   // do something with element
}

Template Method Design Pattern

Type : Behavioral

The template method design pattern is a behavioral design pattern that defines the skeleton of an algorithm in an operation, deferring some steps to subclasses.

It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.

For example, consider a simple algorithm for sorting an array of integers. This algorithm could be implemented using the template method design pattern as follows:

SortArrayAlgorithm {
  public:
  void sort(int[] array) {
    // Sort array
    for (int i = 0; i < array.length; i++) {
       for (int j = i + 1; j < array.length; j++) {
         if (array[i] > array[j]) {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
           }
        }
     }
     // Template method
     void execute() {
       int[] array = {5, 4, 3, 2, 1};
       // Perform sorting
       sort(array);
       // Print sorted array
       for (int i : array) {
         std::cout << i << " ";
       }
       std::cout << std::endl;
   }
};

In the above example, the sort() method is the template method. It defines the overall structure of the algorithm, while deferring the implementation of the sorting logic to the sort() method.

The execute() method is the client code that uses the SortArrayAlgorithm class. It creates an array of integers and then calls the sort() method to sort the array. Finally, it prints the sorted array to the console.

The output of the above program would be:

1 2 3 4 5

Mediator Design Pattern

Type : Behavioral

The mediator pattern is a software design pattern that defines an object that encapsulates how a set of objects interact.

This pattern is considered to be a behavioral pattern due to the way it can alter the program’s running behavior.

Visitor Design Pattern

Type : Behavioral

The visitor design pattern is a way of separating an algorithm from an object structure on which it operates.

A practical result of this separation is the ability to add new operations to existing structures without modifying the structures.

For example, consider a structure consisting of different types of shapes.

We can add a new operation to calculate the area of the shapes without modifying the shape objects themselves.

We would do this by creating a visitor object that contains the area calculation algorithm.

This visitor object would then be passed to each shape object, which would call the appropriate method on the visitor object, passing itself as an argument.

The visitor object would then perform the calculation and return the result.

Another example might be a structure consisting of nodes in a tree. We might want to add a new operation to print out the nodes in reverse order.

We would do this by creating a visitor object that contains the algorithm for printing in reverse order. This visitor object would then be passed to each node in the tree, which would call the appropriate method on the visitor object, passing itself as an argument.

The visitor object would then print out the node in reverse order.

Adapter Design Pattern

Type : Structural

An adapter design pattern is a way of converting the interface of one class into another interface. This is often done to make classes work together that otherwise would not be compatible.

For example, a class that uses a Hashtable to store data would not be compatible with a class that uses an ArrayList. However, by using an adapter design pattern, the two classes can work together.

Proxy Design Pattern

Type : Structural

In computer programming, the proxy pattern is a design pattern used to provide a surrogate or placeholder for another object, in order to control access to it.

A proxy is an object that controls access to another object, called the target object. The proxy may be responsible for creating the target object, forwarding requests to it, or caching results returned from the target object.

There are several reasons for using a proxy:

  • To control access to a resource that is expensive or difficult to create.
  • To hide the complexity of an object or interface.
  • To improve performance by caching results.
  • To reduce security risks by denying direct access to an object.

Proxies are often used in place of direct references to an object. For example, a proxy may be used to represent a file or database connection that is expensive to create or open.

Proxies are also used to hide the complexity of an object or interface. For example, a proxy may be used to represent a complex object that is difficult to create or use. The proxy provides a simplified interface to the complex object.

Proxies may also be used to improve performance by caching results. For example, a proxy may be used to cache the results of a database query. The next time the same query is made, the proxy can return the cached results instead of querying the database again.

Proxies may also be used to reduce security risks by denying direct access to an object. For example, a proxy may be used to represent a file that should not be directly accessed by a user. The proxy can validate a user’s permissions before allowing the user to access the file.

Bridge Design Pattern

Type : Structural

In software engineering, the bridge design pattern is a design pattern used to separate an abstraction from its implementation so that the two can vary independently.

The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.

For example, consider aShape class with a draw() method. We could have a concrete class CircleShape that implements the draw() method to draw a circle. However, we could also have a SquareShape class that implements the draw() method to draw a square.

Now, suppose we want to add a new Shape, TriangleShape. If we use inheritance, we would have to create a new subclass of Shape, TriangleShape, and implement the draw() method.

However, if we use the bridge design pattern, we can create a new class TriangleShape that implements the Shape interface and has a reference to a DrawingAPI object.

The TriangleShape class would delegate the draw() method to the DrawingAPI object. This would allow us to add new Shapes without having to change the Shape class or the DrawingAPI class.

Composite Design Pattern

Type : Structural

Composite design pattern is a structural design pattern that allows us to compose objects into tree structures and then work with these structures as if they were individual objects. This pattern is used in scenarios where there is a need to treat a group of objects in the same way as a single object.

For example, a composite object could be used to represent a directory structure in a file system. Each directory would be a composite object that contains a list of other files and directories.

These files and directories could be manipulated as if they were individual objects, even though they are actually part of a larger structure.

Decorator Design Pattern

Type : Structural

The decorator design pattern is a structural design pattern that allows for the modification of the behavior of an object at runtime. The decorator design pattern is often used in the context of object-oriented programming, to extend the functionality of a class without having to modify the source code of the class.

One common use case for the decorator design pattern is the implementation of security features in software. For example, a decorator could be used to add authentication to a class method. The decorator would check that the user has the appropriate permissions before allowing the method to execute.

Another common use case for the decorator design pattern is the implementation of caching in software. Caching is a technique that is used to improve the performance of software by storing frequently accessed data in memory.

A decorator could be used to cache the results of a method so that subsequent calls to the method do not have to retrieve the data from the database.

There are many other possible use cases for the decorator design pattern. The pattern is very flexible and can be used to implement a wide range of features.

Facade Design Pattern

Type : Structural

A facade is an object that provides a simplified interface to a complex system. A facade is an abstract class that defines a set of interfaces. A facade can provide a default implementation of these interfaces.

A facade can be used to hide the complexity of a system and make it easier to use. A facade can also be used to improve performance by caching the results of expensive operations.

Examples of facade design pattern:

  • The java.io.File class is a facade that provides a simplified interface to the file system.
  • The java.net.URL class is a facade that provides a simplified interface to network resources.
  • The java.sql.Connection class is a facade that provides a simplified interface to database resources.

Flyweight Design Pattern

Type : Structural

The flyweight design pattern is a software design pattern that is used to minimize the memory footprint of a program by sharing data between objects. The flyweight design pattern is often used in conjunction with the Singleton design pattern.

The flyweight design pattern is an optimization technique that is used to minimize the memory footprint of a program by sharing data between objects. The flyweight design pattern is often used in conjunction with the Singleton design pattern.

For example, consider a program that is used to manage a large number of customer records. Each customer record includes the customer’s name, address, and phone number. The customer records are stored in a database.

To minimize the memory footprint of the program, the customer records are stored in a flyweight object. The flyweight object contains the customer’s name, address, and phone number. The customer records are stored in the database, and the customer record flyweight object is stored in the program’s memory.

When a customer record is needed, the program retrieves the customer record flyweight object from memory. The program then sets the customer record flyweight object’s name, address, and phone number properties to the values from the database. The customer record flyweight object is then used by the program.

The flyweight design pattern is an optimization technique that is used to minimize the memory footprint of a program by sharing data between objects. The flyweight design pattern is often used in conjunction with the Singleton design pattern.

For example, consider a program that is used to manage a large number of customer records. Each customer record includes the customer’s name, address, and phone number. The customer records are stored in a database.

To minimize the memory footprint of the program, the customer records are stored in a flyweight object. The flyweight object contains the customer’s name, address, and phone number. The customer records are stored in the database, and the customer record flyweight object is stored in the program’s memory.

When a customer record is needed, the program retrieves the customer record flyweight object from memory. The program then sets the customer record flyweight object’s name, address, and phone number properties to the values from the database. The customer record flyweight object is then used by the program.

Abstract Factory Design Pattern

Type : Creational

The abstract factory design pattern is a creational design pattern that allows for the generation of objects that belong to a certain family. This pattern is useful when there is a need to create objects that have a commonality, but the concrete implementation of these objects may vary.

For example, a family of objects may all be shapes, but the concrete implementation of these shapes may vary depending on the specific application.

In order to use the abstract factory pattern, a class called the abstract factory must be created. This class will contain a method that must be implemented by all concrete factories. This method will return an object that belongs to the family of objects that the abstract factory is responsible for creating.

Concrete factories will then implement the abstract factory and provide a concrete implementation of the object that is to be created. In this way, the abstract factory can be used to create objects without having to know the concrete implementation of these objects.

The abstract factory pattern is useful in situations where there is a need to create objects that have a commonality, but the concrete implementation of these objects may vary. This pattern allows for the decoupling of the client code from the concrete implementation of the objects that it needs to create.

One example of where the abstract factory pattern can be used is in the creation of user interface elements. The concrete implementation of these elements may vary depending on the platform that the application is running on. For example, the concrete implementation of a button may be different on a Windows platform than it is on a Mac platform. By using the abstract factory pattern, the client code can be agnostic of the concrete implementation of the button, and can simply request a button from the abstract factory.

Another example of where the abstract factory pattern can be used is in the creation of database access objects. The concrete implementation of these objects may vary depending on the type of database that is being used. By using the abstract factory pattern, the client code can be agnostic of the concrete implementation of the database access objects, and can simply request these objects from the abstract factory.

Builder Design Pattern

Type : Creational

The builder design pattern is a creational design pattern that allows for the construction of complex objects by specifying only their type and content. The builder design pattern is an object-oriented design pattern that helps to create complex objects by specifying only their type and content. The builder design pattern is a useful tool for creating objects that are both complex and easy to understand.

There are three main parts to the builder design pattern: the builder interface, the concrete builder, and the director. The builder interface defines the methods that must be implemented by the concrete builder. The concrete builder is responsible for creating the object and setting its values. The director is responsible for orchestrating the construction of the object by the concrete builder.

The builder design pattern is beneficial because it allows for the construction of complex objects without the need for the user to understand the internals of the object. The builder design pattern is also easy to use and easy to understand.

There are a few drawbacks to the builder design pattern.

First, the builder design pattern can be used to create objects that are not intended to be used by the user.

Second, the builder design pattern can be used to create objects that are not easily understood by the user.

Factory Method Design Pattern

Type : Creational

Factory Method Design Pattern is a creational design pattern that allows us to create objects while hiding the implementation details and keeping the interface same. This pattern provides an interface for creating objects, and delegates the responsibility of instantiating the object to the subclasses.

For example, let’s say we have an abstract class Shape with a factory method getShape() which returns an object of type Shape. We have concrete subclasses Circle, Rectangle, and Square which override the getShape() method and return an object of their respective type.

When we call the getShape() method with a parameter “circle”, it returns a Circle object, and when we call it with a parameter “rectangle”, it returns a Rectangle object.

Prototype Design Pattern

Type : Creational

The prototype design pattern is a creational design pattern used in software development when the type of object to create is determined by a prototypical instance, which is cloned to produce new objects.

This pattern is used to:

  • avoid subclasses of an object creator in the client application, like the abstract factory pattern does;
  • avoid the inherent cost of creating a new object in the standard way (e.g., using the ‘new’ keyword);
  • initialize an object to values that suit a particular application.

Example:

Suppose we have a Shape class with a ‘draw’ method. We want to be able to create new shapes using a factory object, but we don’t want to have to create a new subclass for each different type of shape.

We can achieve this by cloning a prototype object:

Shape.prototype.clone = function() {
  var clone = new this.constructor();
  clone.copy(this);
  return clone;
}
var Circle = function(x, y, radius) {
  this.x = x;
  this.y = y;
  this.radius = radius;
}
Circle.prototype = Shape.prototype;
var circle = new Circle(10, 10, 5);
var clone = circle.clone();

// The 'clone' object is an instance of the 'Circle' class, 
// with its own x, y and radius properties.

Singleton Design Pattern

Type : Creational

The singleton design pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when only one object is needed to coordinate actions across the system. The singleton pattern is often used to implement logging, configuration, and caching systems.

Leave a Reply

%d bloggers like this: