Patterns creationnels
Singleton
class Database {
private static $instance = null;
private function __construct() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Database();
}
return self::$instance;
}
}
Pour contrôler l'accès à une ressource unique, comme une connexion à la base de données.
Factory Method
interface DocumentFactory {
public function createDocument(): Document;
}
class PDFDocumentFactory implements DocumentFactory {
public function createDocument() {
return new PDFDocument();
}
}
class PDFDocument {
// PDF specific methods
}
Pour créer des objets sans spécifier la classe exacte à utiliser.
Patterns structurels
Adapter
interface Target {
public function request(): string;
}
class Adaptee {
public function specificRequest(): string {
return "Adaptee Specific Request";
}
}
class Adapter implements Target {
private $adaptee;
public function __construct(Adaptee $adaptee) {
$this->adaptee = $adaptee;
}
public function request(): string {
return "Adapter: " . strrev($this->adaptee->specificRequest());
}
}
Pour adapter l'interface d'un objet à une interface attendue par le client.
Decorator
interface Component {
public function operation(): string;
}
class ConcreteComponent implements Component {
public function operation() {
return "ConcreteComponent";
}
}
abstract class Decorator implements Component {
protected $component;
public function __construct(Component $component) {
$this->component = $component;
}
public function operation(): string {
return $this->component->operation();
}
}
class ConcreteDecoratorA extends Decorator {
public function operation() {
return "ConcreteDecoratorA(" . parent::operation() . ")";
}
}
Pour ajouter des responsabilités à un objet dynamiquement, sans modifier sa structure.
Patterns comportementaux
Observer
interface Observer {
public function update(string $message);
}
class ConcreteObserver implements Observer {
public function update(string $message) {
echo "Received: " . $message;
}
}
class Subject {
private $observers = [];
private $state;
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function setState($state) {
$this->state = $state;
$this->notify();
}
private function notify() {
foreach ($this->observers as $observer) {
$observer->update($this->state);
}
}
}
Pour mettre en place un mécanisme de publication/abonnement, où les objets peuvent être notifiés automatiquement des changements d'état.
Strategy
interface PaymentStrategy {
public function pay(int $amount): void;
}
class CreditCardPayment implements PaymentStrategy {
public function pay(int $amount) {
echo "Paid with credit card: " . $amount;
}
}
class PayPalPayment implements PaymentStrategy {
public function pay(int $amount) {
echo "Paid with PayPal: " . $amount;
}
}
class ShoppingCart {
private $paymentStrategy;
public function setPaymentStrategy(PaymentStrategy $strategy) {
$this->paymentStrategy = $strategy;
}
public function checkout(int $amount) {
$this->paymentStrategy->pay($amount);
}
}
Pour définir une famille de algorithms, encapsuler chaque algorithm dans sa propre classe, et rendre les algoritms interchangeables.
Command
interface Command {
public function execute();
}
class LightOnCommand implements Command {
private $light;
public function __construct(Light $light) {
$this->light = $light;
}
public function execute() {
$this->light->on();
}
}
class Light {
public function on() {
echo "Light is ON";
}
}
class RemoteControl {
private $command;
public function setCommand(Command $command) {
$this->command = $command;
}
public function pressButton() {
$this->command->execute();
}
}
Pour encapsuler une requête comme un objet, permettant de paramétrer des clients avec différentes requêtes, et enregistrer ou déclencher des événements à l'occasion de la requête.