Skip to content
Design Patterns

Structural Patterns

Organize objects and classes to form larger structures and provide relationships between them.

Adapter

The Adapter pattern allows objects with incompatible interfaces to work together by providing a common interface that both objects can understand. It acts as a bridge between two incompatible interfaces, converting the interface of one object into another interface that clients expect.

  • Use case: Converting data from one format to another (e.g., JSON to XML)
  • Use case: Wrapping a third-party library with a simplified interface
  • Use case: Making an old API compatible with a new version

InShort: bridge between incompatible interfaces

Bridge

The Bridge pattern decouples an abstraction from its implementation, allowing the two to vary independently. It involves creating two separate class hierarchies: one for the abstraction and another for the implementation, and using a bridge object to connect them.

  • Use case: Connecting different database engines to an application
  • Use case: Implementing support for multiple rendering engines in a web framework
  • Use case: Decoupling GUI components from underlying operating systems

InShort: decouples abstraction from its implementation

Composite

The Composite pattern allows you to treat a group of objects as a single object. It lets clients treat individual objects and compositions of objects uniformly by using a common interface. This pattern is useful when you need to represent a part-whole hierarchy.

  • Use case: Representing a tree structure of elements
  • Use case: Creating nested components in a user interface
  • Use case: Building menus with submenus

InShort: treat a group of objects as a single object

Decorator

The Decorator pattern allows you to add new functionality to an existing object dynamically. It involves creating a decorator class that wraps the original object and provides additional behaviors without modifying the underlying object.

  • Use case: Adding logging functionality to a function or method
  • Use case: Adding validation to a form input field
  • Use case: Adding authentication to an API endpoint

InShort: add new functionality to an existing object dynamically

Facade

The Facade pattern provides a simplified interface to a complex system or set of classes. It encapsulates the complexity of the underlying subsystem and provides a single entry point for clients to access the system’s features.

  • Use case: Providing a high-level API for a library or framework
  • Use case: Hiding the implementation details of a complex module
  • Use case: Simplifying the interface of a set of related classes

InShort: simplified interface to a complex system

Flyweight

The Flyweight pattern is used to minimize memory usage by sharing data across multiple similar objects. It involves separating the intrinsic (shared) state from the extrinsic (unique) state of an object, and sharing the intrinsic state among multiple instances.

  • Use case: Caching frequently used data in a game engine
  • Use case: Optimizing memory usage in a text editor for characters with the same font and size
  • Use case: Storing shared data in a social media feed with multiple posts

InShort: minimizes memory usage by sharing data among objects

Mixin

The Mixin pattern allows you to dynamically extend the functionality of an object by “mixing in” additional behavior from one or more mixins. Mixins are a way to achieve code reuse without inheritance, allowing objects to borrow methods and properties from multiple sources.

  • Use case: Adding event handling capabilities to an object
  • Use case: Mixing in utility functions to provide common functionalities
  • Use case: Enhancing an object with serialization or cloning methods

InShort: dynamically extend object functionality through mixins

Proxy

The Proxy pattern provides a surrogate or placeholder object that controls access to another object, allowing you to add extra behavior before or after the target object’s methods are invoked. It can be used to implement features such as lazy loading, caching, access control, and logging.

  • Use case: Caching data from an API response
  • Use case: Implementing access control for sensitive resources
  • Use case: Logging method invocations for debugging purposes

InShort: provides a surrogate object with additional behavior control


Mnemonic:

  • Adapter (A) - Picture an adapter that allows you to plug in incompatible electronic devices, symbolizing how the adapter pattern bridges the gap between incompatible interfaces.

  • Bridge (B) - Visualize a bridge connecting two separate land masses, representing how the bridge design pattern connects the abstraction and implementation parts of a system.

  • Composite (C) - Visualize a group of musical notes coming together to form a harmonious chord, symbolizing how the composite pattern treats a collection of objects as a single object.

  • Decorator (D) - Picture a beautifully decorated cake, where new layers and decorations are added to enhance its appearance and taste, reflecting how the decorator pattern adds new functionality to an existing object dynamically.

  • Flyweight (F) - Imagine a group of people in a company using the same blueprint to build separate houses. This represents how the flyweight pattern minimizes memory usage by sharing data among objects.

  • Facade (F) - Imagine a building with an elegant and simple front (facade) that hides the complex inner workings of the building.

  • Mixin (M) - Picture a painter’s palette with various colors mixed together, representing the dynamic extension of object functionality through mixins. Just like the painter includes different colors into their artwork, objects can include mixin functionality dynamically.

  • Proxy (P) - Imagine a receptionist at the entrance of an office building, controlling access to visitors and acting as an intermediary between them and the employees inside.


ABCDFFMP