sub-title

Also check Orama's Quora and Orama's GitHub
I shall not claim to know so much, but only that I learn new things everyday

Wednesday, 13 July 2022

Software Design Pattern: The Patterns I first used without much knowing

Introduction

In my software engineering career, there are certain thing that I did without much knowing that I was doing them. Although I would understand and appreciate their usage, I would sometimes not know that I am doing something fundamental in software engineering.

It took me time to realize that Decorators, Dependency Injection, Factory, etc – which I had already extensively used – actually belonged to the much-talked-about concept of Design Patterns.


What is Design Pattern

In software engineering, a Design Pattern is a general repeatable (reusable) solution to a commonly occurring problem in software design. It is just a description or template (not code or library) for how to solve a problem that can be used in many different situations.

Design patterns are a well-described solution to the most commonly encountered problems which occur during software development. Design patterns represent the best practices developed over a period of time by experienced Object-Oriented software developers to produce better code. They promote re-usability, which leads to a more robust and maintainable code.

In summary, Design Patterns are repeatable solutions to common problems.


Classification of Design Patterns

Design Patterns are categorized mainly into three categories (Creational, Structural, and Behavioral) depending on their level of detail, complexity, and scale of applicability to the entire system being designed.
There are also two other types of patterns - idioms and architectural patterns, which we will not cover in this post.

1. Creational Design Pattern

This pattern allows us to create objects or classes in such a way that our code becomes more flexible and reusable. They reduce the dependency and control how the use interaction with our class so we don’t have to deal with complexities. Below are the various design pattern of creational design pattern.

  • Abstract Factory- create objects without specifying their concrete type. Creates a family of related objects.
  • Builder - create complex objects.
  • Factory Method - create objects without specifying the exact class to create.
  • Prototype - create a new object from the existing object.
  • Singleton - restricts object creation for a class to only one instance.



2. Structural Design Patterns

This pattern allows us to create objects or classes in such a way that our code becomes more readable and maintainable. It assembles objects and classes into a larger structure which is more flexible and efficient. It also ensures that functionalities are properly separated or encapsulated. It reduces the interface between interdependent things. Examples are below:

  • Adapter – provide for two incompatible classes to work together by wrapping an interface around one of the existing classes.
  • Composite - wrap a group of objects into a single object.
  • Bridge - decouple an abstraction so that two classes can vary independently. A method to decouple an interface from its implementation.
  • Decorator - extend the object behaviour dynamically at run time.
  • Facade - offer a simple interface to more complex underlying objects.
  • Flyweight - decrease the cost of complex object model.
  • Proxy - represent an object with another object to enable access control, reduce cost and reduce complexity.



3. Behavioural Design Pattern

Behavioural Design Patterns are responsible for how one class communicates with others.

  • Chain of Responsibility - represent the command to a chain of processing object.
  • Command - generate the objects which encapsulate actions of parameters.
  • Interpreter - implement a specialized language.
  • Iterator - access all the elements of an object sequentially without violating its underlying representation.
  • Mediator - provide loose coupling between classes by being the only class that has detailed knowledge of their existing methods.
  • Memento - restore an object in the previous state.
  • Observer - allow a number of observer objects to see an event. Defines how to notify objects of changes made to other object(s).
  • State - allow an object to modify its behaviour when it's internal states changes.
  • Strategy - provides one of the families of algorithm to be selected at runtime. Encapsulates an algorithm inside a class.
  • Template Method - allow subclasses to provide concrete behaviour. It also defines the skeleton of an algorithm as an abstract class.
  • Visitor - separate an algorithm from an object structure by moving the hierarchy of methods into one object.



Reflection on some Design Patterns I commonly use

Decorator pattern allows a user to add new functionality to an existing object without altering its structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class.


Dependency Injection
makes it easy to create loosely coupled components, which typically means that components consume functionality defined by interfaces without having any first-hand knowledge of which implementation classes are being used.
Dependency injection makes it easier to change the behaviour of an application by changing the components that implement the interfaces that define application features. It also results in components that are easier to isolate for unit testing.


Factory pattern is one of most used design pattern and comes under creational patterns category.
In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

In proxy pattern, a class represents functionality of another class. This type of design pattern comes under structural pattern.
In proxy pattern, we create object having original object to interface its functionality to outer world.


Facade pattern hides the complexities of the system and provides an interface to the client using which the client can access the system. This type of design pattern comes under structural pattern as this pattern adds an interface to existing system to hide its complexities.


Observer pattern (also known as Publish-Subscribe Pattern) is used when there is one-to-many relationship between objects such as if one object is modified, its dependent objects are to be notified automatically. Observer pattern falls under behavioural pattern category.
An object with a one-to-many relationship with other objects who are interested in its state is called the subject or publisher. The observers are notified whenever the state of the subject changes and can act accordingly. The subject can have any number of dependent observers which it notifies, and any number of observers can subscribe to the subject to receive such notifications.
Observer pattern uses two actor classes:
•    The Observer (os Subscriber) abstract class provides an update() method which will be called by the subject to notify it of the subject’s state change.
•    The Subject (or Publisher) class is also an abstract class and defines four primary methods: attach(), detach(), setState(), and notify()


Conclusion

A pattern is a proven general solution for a specific problem in a specific context. Therefore, if a problem reoccurs and it follows a certain existing pattern, you simply have to apply that pattern. Apply patterns on a case-by-case basis.

Some problems appear very often in software engineering such as the notification of interested parties by a subject about specific events where the Observer pattern or the (more general) Publisher-Subscriber pattern might be applicable. In such cases, one may apply the Observer pattern if it works well for that situation.

Do not use a pattern blindly, just because there is such and such a Design Pattern. Rather, let the problem at hand determine whether or not to use a pattern. For example, if you want to apply a certain logic to several functions (or objects or classes) in your code, it is obvious to use the Decorator Design Pattern.

Final tip of the day: Decoupled, or decoupling, is a state of an IT environment in which two or more systems somehow work or are connected without being directly connected. In a decoupled microservices architecture, for example, software services have none or very little knowledge about the other services.

No comments:

Post a Comment