Software design patterns are general, reusable solutions to commonly occurring problems within a given context in software design. They represent best practices and can speed development by providing tested, proven development paradigms.

Categories of Patterns Link to heading

Design patterns can be categorized based on their intent or purpose. There are 3 broad categories that design patterns are dived into - Creational, Structural, and Behavioral

Creational Patterns Link to heading

Creational patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or add complexity to the design. Creational design patterns solve this problem by controlling the creation of this object. Examples include:

  • Factory Method
  • Abstract Factory
  • Builder
  • Singleton

Structural Patterns Link to heading

Structural patterns explain how to assemble objects and classes into larger structures while keeping the structures flexible and efficient. Examples include:

  • Composite
  • Decorator
  • Facade
  • Adapter
  • Proxy

Behavioral Patterns Link to heading

Behavioral patterns are about identifying common communication patterns between objects and realizing these patterns. Examples include:

  • State
  • Command
  • Chain of Responsibility
  • Observer
  • Strategy
  • Iterator
  • Mediator
  • Template

Design Principles Link to heading

Design principles guide us to design better software. They are like a beacon guiding a lost sailor. The most important principles are “Keep it simple” and “Loose coupling.” Other principles include:

  • Keep it flexible
  • Separation of concern
  • Principle of modularity
  • DRY: don’t repeat yourself
  • SOLID: Single responsibility principle, open-closed principle, Liskov substitution principle, Interface segregation principle, Dependency inversion principle

Facade (Service class) Link to heading

The Facade pattern provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Advantages include:

  • Shields clients from subsystem components, thereby reducing the number of objects that clients deal with, making the system easier to use.
  • Promotes weak coupling between the client and subsystem.

Strategy Pattern Link to heading

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Advantages include:

  • We can easily add new algorithms without changing the context class.
  • The Strategies are better reusable.
  • Very extendable.

Disadvantages include:

  • Clients must know the existence of different strategies, and a client must understand how the strategies differ.
  • It increases the number of objects in the application.

Template Method Link to heading

The Template Method pattern defines the skeleton of an algorithm in a superclass but lets subclasses override specific steps of the algorithm without changing its structure. Advantages include:

  • No code duplication.
  • Reusable code.
  • Easy to implement and readable.
  • Flexible.
  • Clean Architecture.

Disadvantages include:

  • It might violate the Liskov Substitution principle by suppressing a default step implementation via a subclass.
  • Enforces a particular design.
  • Maintenance issue.

Observer Pattern Link to heading

The Observer pattern defines a one-to-many dependency between objects so that all its dependents are notified and updated automatically when one object changes state. Advantages include:

  • Loose coupling.
  • Open closed principle.
  • Easy to add new observers.

Composite Pattern Link to heading

The Composite pattern composes objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Advantages include:

  • Lean, easy-to-understand code.
  • Great expandability.

Disadvantages include:

  • Complicate implementation.

Iterator Pattern Link to heading

The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Command Pattern Link to heading

The Command pattern encapsulates a request as an object, letting you parameterize clients with queues, requests, and operations.

In conclusion, understanding and applying design patterns improves code readability, testability, and maintainability and allows developers to communicate using well-known, understood terminology.