Skip to main content
Design Pattern

Design Patterns

A design pattern is a tried and true, reusable solution to a repeating software design problem. A design pattern is not a code, but a template or guideline that can structure code in the most effective way.

Benefits of design pattern are -- 

  • Code Reusability
    • Provide standardized solutions that can be reused across multiple modules and projects.
    • Less repeated code and reduced bugs because the logic exists in one place.

    • Example:

      • The Factory Pattern lets you reuse the same object creation logic for different classes.

      • Instead of writing new code every time you create an object, the factory handles it.

  • Scalability
    • Patterns make it easy to extend your system without rewriting existing code.

    • You can scale features, add components, or support new requirements without modifying the core logic.

    • Example:

      • With Observer Pattern, you can add new subscribers easily as the system grows.

  • Maintainability
    • Encourage separation of concerns, meaning each class has one purpose.

    • When something breaks, debugging becomes easier because the responsibility is clearly isolated. Developers can fix or update parts of the system without worrying about side effects.

    • Example:

      • The MVC Pattern separates business logic, UI, and data layers.

  • Readability
    • Design patterns provide well-understood structures that most developers easily recognize.

    • New team members can understand the system faster.

    • Code becomes self-explanatory because the architecture follows familiar patterns.

    • Example:

      • If another developer sees a code, they immediately understand what’s happening.

      • Design patterns reduce “mystery code” and bring clarity to large projects.

  • Types of Design Patterns (3 Main Categories)
CategoryDescriptionExample Pattern
CreationalHow objects are created and managedSingleton, Factory
StructuralHow classes and objects are composedAdapter, Decorator
BehavioralHow objects communicateObserver, Strategy
  • Real-Life Examples (with PHP/Drupal relevance)

     1. Singleton Pattern – One Instance Only

        Problem: You need one instance of a class across your entire application (e.g., database connection).

        Real-life example: Think of a printer spooler - multiple print requests, but only one printer managing them.

       Used in Drupal services to manage shared resources like cache, logger, or DB connections.

    2. Factory Pattern – Object Creation Logic in One Place

        Problem: You need to create objects without exposing creation logic everywhere.

        Real-life example: Car factory produces cars — you request a car, not the details of how it’s assembled.

class ShapeFactory {
  public static function create($type) {
    switch ($type) {
      case 'circle': return new Circle();
      case 'square': return new Square();
      default: throw new Exception('Unknown shape');
    }
  }
}

       Used in Drupal plugin managers — they dynamically create plugin objects based on configuration.

    3. Observer Pattern – Event-Based Notifications

        Problem: Many parts of your system need to react when something happens.

        Real-life example: You subscribe to a YouTube channel. When the creator uploads a video, all subscribers get notified.

        In Drupal:

       a) Event Dispatcher system works on this pattern.

       b) When a node is saved, multiple event subscribers (modules) can react.

// Example: Custom event subscriber in Drupal.
class NodeSaveSubscriber implements EventSubscriberInterface {
  public static function getSubscribedEvents() {
    return [NodeEvents::INSERT => 'onNodeInsert'];
  }

  public function onNodeInsert(NodeEvent $event) {
    $node = $event->getNode();
    // Perform actions after node creation.
  }
}

   3. Decorator Pattern – Add Functionality Dynamically

        Problem: You want to enhance behavior without altering the original class.

        Real-life example: A coffee shop — you start with plain coffee and add milk, sugar, cream — each decorates the original         coffee.

       Used in Drupal render arrays and service decoration (e.g., altering core service behavior).

interface Coffee {
  public function cost();
}

class SimpleCoffee implements Coffee {
  public function cost() { return 50; }
}

class MilkDecorator implements Coffee {
  protected $coffee;
  public function __construct(Coffee $coffee) { $this->coffee = $coffee; }
  public function cost() { return $this->coffee->cost() + 20; }
}