Fundamentals 7 min read

PHP Design Patterns: Singleton, Factory, Registry, Adapter, and Observer

This article introduces common PHP design patterns—including Singleton, Factory, Registry, Adapter, and Observer—explaining their purpose, structure, typical use cases, and providing complete code examples for each pattern to illustrate how they can be implemented in object‑oriented applications.

Laravel Tech Community
Laravel Tech Community
Laravel Tech Community
PHP Design Patterns: Singleton, Factory, Registry, Adapter, and Observer

Design patterns represent best practices for solving recurring software design problems. The article begins with a brief overview of design patterns and then presents five widely used patterns with explanations and full PHP implementations.

1. Singleton Pattern ensures a class has only one instance and provides a global access point. It is useful for managing shared resources such as configuration or logging.

<?php
class Singleton {
    private static $instance;
    private function __construct() { $this->runtime = time(); }
    private function __clone() {}
    private function __wakeup() {}
    public static function getInstance() {
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    public function run() { echo $this->runtime, PHP_EOL; }
}
$a = Singleton::getInstance();
$a->run();
?>

2. Factory Pattern abstracts object creation behind a common interface, allowing client code to remain independent of concrete classes. The example defines an abstract Operation class, concrete OperationAdd and OperationSub implementations, and a Factory that creates the appropriate operation based on a symbol.

<?php
abstract class Operation {
    abstract public function getValue($num1, $num2);
}
class OperationAdd extends Operation {
    public function getValue($num1, $num2) { return $num1 + $num2; }
}
class OperationSub extends Operation {
    public function getValue($num1, $num2) { return $num1 - $num2; }
}
class Factory {
    public static function createObj($operate) {
        switch ($operate) {
            case '+': return new OperationAdd();
            case '-': return new OperationSub();
        }
    }
}
$test = Factory::createObj('+');
echo $test->getValue(2,3);
?>

3. Registry (Registration) Pattern provides a global store for objects, allowing them to be retrieved by a key. The example shows a Single singleton and a Register class that maps aliases to objects.

<?php
class Single {
    public $hash;
    private static $ins = null;
    private function __construct() { $this->hash = rand(1,9999); }
    public static function getInstance() {
        if (self::$ins instanceof self) return self::$ins;
        self::$ins = new self();
        return self::$ins;
    }
}
class Register {
    protected static $objects = [];
    public static function set($alias,$object){ self::$objects[$alias] = $object; }
    public static function get($alias){ return self::$objects[$alias]; }
    public static function _unset($alias){ unset(self::$objects[$alias]); }
}
Register::set('rand', Single::getInstance());
$object = Register::get('rand');
print_r($object);
?>

4. Adapter Pattern acts as a bridge between incompatible interfaces. The article defines a Target interface, an Adaptee class with its own methods, and an Adapter that implements Target while delegating calls to an Adaptee instance.

<?php
interface Target { public function simpleMethod1(); public function simpleMethod2(); }
class Adaptee { public function simpleMethod1(){ echo 'Adapter simpleMethod1
'; } }
class Adapter implements Target {
    private $adaptee;
    public function __construct(Adaptee $adaptee){ $this->adaptee = $adaptee; }
    public function simpleMethod1(){ $this->adaptee->simpleMethod1(); }
    public function simpleMethod2(){ echo 'Adapter simpleMethod2
'; }
}
class Client { public static function main(){
    $adaptee = new Adaptee();
    $adapter = new Adapter($adaptee);
    $adapter->simpleMethod1();
    $adapter->simpleMethod2();
}}
Client::main();
?>

5. Observer Pattern defines a one‑to‑many dependency so that when the subject changes, all observers are automatically notified. The example includes Subject and Observer interfaces, an Action class implementing Subject , and concrete observers ( Cat , Dog , People ) that react to notifications.

<?php
interface Subject { public function register(Observer $o); public function notify(); }
interface Observer { public function watch(); }
class Action implements Subject {
    private $_observers = [];
    public function register(Observer $o){ $this->_observers[] = $o; }
    public function notify(){ foreach($this->_observers as $o){ $o->watch(); } }
}
class Cat implements Observer { public function watch(){ echo "Cat watches TV
"; } }
class Dog implements Observer { public function watch(){ echo "Dog watches TV
"; } }
class People implements Observer { public function watch(){ echo "People watches TV
"; } }
$action = new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();
?>

Each pattern section concludes with a short usage example, demonstrating how the pattern can be applied in real PHP code. The article provides a practical reference for developers seeking to improve code maintainability and flexibility through proven design patterns.

design patternsPHPsingletonadapterFactoryObserver
Laravel Tech Community
Written by

Laravel Tech Community

Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.