Design patterns are proven solutions to common problems in software development. Implementing these patterns can improve code maintainability and scalability. This guide provides practical examples of popular design patterns in a step-by-step manner.
Singleton Pattern
The Singleton pattern ensures a class has only one instance and provides a global point of access to it. It is useful for managing shared resources such as database connections.
Example implementation:
Step 1: Create a class with a private static variable to hold the instance.
Step 2: Make the constructor private to prevent direct instantiation.
Step 3: Provide a public static method to access the instance.
Code snippet:
class Singleton { private static $instance = null; private function __construct() { // Initialization code } public static function getInstance() { if (self::$instance === null) { self::$instance = new Singleton(); } return self::$instance; }
}
Factory Pattern
The Factory pattern provides an interface for creating objects but allows subclasses to alter the type of objects that will be created. It promotes loose coupling.
Example implementation:
Step 1: Define a common interface for products.
Step 2: Create concrete classes implementing the interface.
Step 3: Implement a factory class with a method to instantiate objects based on input.
Code snippet:
interface Product { public function getType();
} class ProductA implements Product { public function getType() { return 'A'; }
} class ProductB implements Product { public function getType() { return 'B'; }
} class Factory { public static function create($type) { if ($type === 'A') { return new ProductA(); } elseif ($type === 'B') { return new ProductB(); } return null; }
}
Observer Pattern
The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically. It is useful for event handling systems.
Example implementation:
Step 1: Create an interface for observers.
Step 2: Implement concrete observers.
Step 3: Create a subject class that maintains a list of observers and notifies them of changes.
Code snippet:
interface Observer { public function update($data);
} class ConcreteObserver implements Observer { public function update($data) { // Handle update }
} class Subject { private $observers = []; public function attach(Observer $observer) { $this->observers[] = $observer; } public function notify($data) { foreach ($this->observers as $observer) { $observer->update($data); } }
}