Design Patterns
⏱ 22 min read read
1. Singleton Pattern:
Ensures only ONE instance of a class exists. Useful for database
connections, config, loggers.
class AppConfig {
private static ?AppConfig $instance = null;
private array $settings = [];
private function \_\_construct() {
$this->settings['db_url'] = 'mysql://localhost/mydb';
}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function get(string $key): mixed {
return $this->settings[$key] ?? null;
}
}
$c1 = AppConfig::getInstance();
$c2 = AppConfig::getInstance();
var_dump($c1 === $c2); // bool(true) --- same object!
2. Builder Pattern:
Constructs complex objects step-by-step with method chaining (return
$this).
class QueryBuilder {
private string $table = '';
private array $conditions = [];
private ?int $limit = null;
public function from(string $table): self { $this->table =
$table; return $this; }
public function where(string $cond): self { $this->conditions[]
= $cond; return $this; }
public function limit(int $n): self { $this->limit = $n; return
$this; }
public function build(): string {
$sql = "SELECT * FROM {$this->table}";
if ($this->conditions) $sql .= ' WHERE ' . implode(' AND ',
$this->conditions);
if ($this->limit !== null) $sql .= " LIMIT {$this->limit}";
return $sql;
}
}
$sql = (new QueryBuilder())->from('users')->where('age >
18')->limit(10)->build();
3. Observer Pattern:
Objects subscribe to events. When something happens, all subscribers are
notified.
Ensures only ONE instance of a class exists. Useful for database
connections, config, loggers.
class AppConfig {
private static ?AppConfig $instance = null;
private array $settings = [];
private function \_\_construct() {
$this->settings['db_url'] = 'mysql://localhost/mydb';
}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function get(string $key): mixed {
return $this->settings[$key] ?? null;
}
}
$c1 = AppConfig::getInstance();
$c2 = AppConfig::getInstance();
var_dump($c1 === $c2); // bool(true) --- same object!
2. Builder Pattern:
Constructs complex objects step-by-step with method chaining (return
$this).
class QueryBuilder {
private string $table = '';
private array $conditions = [];
private ?int $limit = null;
public function from(string $table): self { $this->table =
$table; return $this; }
public function where(string $cond): self { $this->conditions[]
= $cond; return $this; }
public function limit(int $n): self { $this->limit = $n; return
$this; }
public function build(): string {
$sql = "SELECT * FROM {$this->table}";
if ($this->conditions) $sql .= ' WHERE ' . implode(' AND ',
$this->conditions);
if ($this->limit !== null) $sql .= " LIMIT {$this->limit}";
return $sql;
}
}
$sql = (new QueryBuilder())->from('users')->where('age >
18')->limit(10)->build();
3. Observer Pattern:
Objects subscribe to events. When something happens, all subscribers are
notified.
Log in to track your progress and earn badges as you complete lessons.
Log In to Track Progress