Common Design Patterns in PHP: Singleton, Factory, Observer, and Adapter
This article introduces four essential PHP design patterns—Singleton, Factory, Observer, and Adapter—explaining their purpose, providing complete code examples, and showing how they improve code maintainability, extensibility, and flexibility in backend development.
In advanced PHP development, understanding common design patterns is a key skill; patterns provide proven solutions that help write more maintainable, extensible, and flexible code.
Singleton Pattern
The Singleton pattern ensures a class has only one instance. In PHP it can be implemented using static methods and properties.
<code>class Database {
private static $instance;
private function __construct() {
// prevent external instantiation
}
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new Database();
}
return self::$instance;
}
// ...
}</code>By making the constructor private, the class cannot be instantiated elsewhere; the getInstance method returns the sole instance, creating it on first call.
Factory Pattern
The Factory pattern creates objects based on given parameters, allowing different types to be instantiated through a single interface.
<code>interface Shape {
public function draw();
}
class Circle implements Shape {
public function draw() {
// draw a circle
}
}
class Rectangle implements Shape {
public function draw() {
// draw a rectangle
}
}
class ShapeFactory {
public static function create($type) {
if ($type == 'circle') {
return new Circle();
} else if ($type == 'rectangle') {
return new Rectangle();
} else {
throw new Exception('Invalid shape type.');
}
}
}
// Usage
$circle = ShapeFactory::create('circle');
$rectangle = ShapeFactory::create('rectangle');
</code>The example defines two shape classes ( Circle and Rectangle ) and a ShapeFactory that creates the appropriate object based on the supplied type.
Observer Pattern
The Observer pattern establishes a one‑to‑many dependency so that when a subject changes state, all its observers are notified. PHP’s SplSubject and SplObserver interfaces facilitate this.
<code>class User implements SplSubject {
private $name;
private $email;
private $observers;
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
$this->observers = new SplObjectStorage();
}
public function attach(SplObserver $observer) {
$this->observers->attach($observer);
}
public function detach(SplObserver $observer) {
$this->observers->detach($observer);
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function setName($name) {
$this->name = $name;
$this->notify();
}
public function setEmail($email) {
$this->email = $email;
$this->notify();
}
// ...
}
class EmailNotifier implements SplObserver {
public function update(SplSubject $subject) {
// send email about name/email change
}
}
// Create user and attach observer
$user = new User('John Doe', '[email protected]');
$user->attach(new EmailNotifier());
// Changing state triggers notifications
$user->setName('Jane Doe');
$user->setEmail('[email protected]');
</code>The User class implements SplSubject and notifies attached observers (e.g., EmailNotifier ) whenever its name or email changes.
Adapter Pattern
The Adapter pattern converts one interface into another compatible one. In PHP, an adapter class can wrap an existing implementation to match a different interface.
<code>interface Csv {
public function outputCsv($data);
}
class CsvWriter implements Csv {
public function outputCsv($data) {
// output CSV
}
}
interface Json {
public function outputJson($data);
}
class JsonWriter implements Json {
public function outputJson($data) {
// output JSON
}
}
class CsvToJsonAdapter implements Json {
private $csvWriter;
public function __construct(Csv $csvWriter) {
$this->csvWriter = $csvWriter;
}
public function outputJson($data) {
// convert CSV data to JSON
$csvData = implode(',', $data);
$json = json_encode($csvData);
return $json;
}
}
// Usage
$csvWriter = new CsvWriter();
$jsonWriter = new CsvToJsonAdapter($csvWriter);
</code>The example defines Csv and Json interfaces, concrete writers for each format, and a CsvToJsonAdapter that implements Json by internally using a CsvWriter to transform data.
Understanding and applying these design patterns—Singleton, Factory, Observer, and Adapter—enables PHP developers to write higher‑quality backend code that is easier to maintain, extend, and adapt to changing requirements.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.