diff --git a/source/concept/poo/general.md b/source/concept/poo/general.md index 4de1ee14b92913b9ecd2bc5fdc4bfc26dddeb13e..ab1d7f349443605db091655295d9281dc6510b6d 100644 --- a/source/concept/poo/general.md +++ b/source/concept/poo/general.md @@ -217,8 +217,187 @@ class CatFactory implements AnimalFactory { } ``` - Abstract Factory : fournit une interface pour créer des familles d'objets liés ou dépendants sans spécifier leurs classes concrètes. +```php +// Produit abstrait A +interface AbstractProductA { + public function operationA(); +} + +// Produit abstrait B +interface AbstractProductB { + public function operationB(); +} + +// Implémentation concrète du produit A +class ConcreteProductA1 implements AbstractProductA { + public function operationA() { + echo "Opération A pour le produit A1\n"; + } +} + +// Implémentation concrète du produit B +class ConcreteProductB1 implements AbstractProductB { + public function operationB() { + echo "Opération B pour le produit B1\n"; + } +} + +// Fabrique abstraite +interface AbstractFactory { + public function createProductA(): AbstractProductA; + public function createProductB(): AbstractProductB; +} + +// Implémentation concrète de la fabrique abstraite +class ConcreteFactory1 implements AbstractFactory { + public function createProductA(): AbstractProductA { + return new ConcreteProductA1(); + } + + public function createProductB(): AbstractProductB { + return new ConcreteProductB1(); + } +} + +// Client utilisant la fabrique abstraite +class Client { + private $productA; + private $productB; + + public function __construct(AbstractFactory $factory) { + $this->productA = $factory->createProductA(); + $this->productB = $factory->createProductB(); + } + + public function execute() { + $this->productA->operationA(); + $this->productB->operationB(); + } +} + +// Utilisation de l'Abstract Factory +$factory = new ConcreteFactory1(); +$client = new Client($factory); +$client->execute(); +``` - Builder : permet de construire un objet complexe étape par étape, en séparant le processus de construction de la représentation finale de l'objet. +```php +// Produit final +class Product { + private $partA; + private $partB; + private $partC; + + public function setPartA($partA) { + $this->partA = $partA; + } + + public function setPartB($partB) { + $this->partB = $partB; + } + + public function setPartC($partC) { + $this->partC = $partC; + } + + public function getInfo() { + return "Part A: " . $this->partA . ", Part B: " . $this->partB . ", Part C: " . $this->partC; + } +} + +// Builder abstrait +abstract class Builder { + protected $product; + + public function createProduct() { + $this->product = new Product(); + } + + public abstract function buildPartA(); + public abstract function buildPartB(); + public abstract function buildPartC(); + + public function getProduct() { + return $this->product; + } +} + +// Implémentation concrète du builder +class ConcreteBuilder extends Builder { + public function buildPartA() { + $this->product->setPartA("Part A built"); + } + + public function buildPartB() { + $this->product->setPartB("Part B built"); + } + + public function buildPartC() { + $this->product->setPartC("Part C built"); + } +} + +// Directeur +class Director { + private $builder; + + public function setBuilder(Builder $builder) { + $this->builder = $builder; + } + + public function buildProduct() { + $this->builder->createProduct(); + $this->builder->buildPartA(); + $this->builder->buildPartB(); + $this->builder->buildPartC(); + + return $this->builder->getProduct(); + } +} + +// Utilisation du pattern Builder +$builder = new ConcreteBuilder(); +$director = new Director(); +$director->setBuilder($builder); +$product = $director->buildProduct(); +echo $product->getInfo(); +``` - Prototype : permet de créer de nouvelles instances en clonant des objets existants, évitant ainsi les coûts de création d'objets à partir de zéro. +```php +// Prototype abstrait +abstract class Prototype { + protected $name; + + public abstract function clone(): Prototype; + + public function getName() { + return $this->name; + } + + public function setName($name) { + $this->name = $name; + } +} + +// Implémentation concrète du prototype +class ConcretePrototype extends Prototype { + public function __construct() { + $this->name = "ConcretePrototype"; + } + + public function clone(): Prototype { + return clone $this; + } +} + +// Utilisation du pattern Prototype +$prototype = new ConcretePrototype(); +$clone = $prototype->clone(); +$clone->setName("Clone"); + +echo "Prototype: " . $prototype->getName() . "\n"; +echo "Clone: " . $clone->getName(); +``` ### Patterns structurels @@ -358,6 +537,46 @@ class Manager implements Employee { } ``` - Proxy : fournit un substitut ou une représentation de substitution pour un objet afin de contrôler son accès. +```php +// Sujet abstrait +interface Subject { + public function request(); +} + +// Sujet concret +class RealSubject implements Subject { + public function request() { + echo "RealSubject: Traitement de la requête.\n"; + } +} + +// Proxy +class Proxy implements Subject { + private $realSubject; + + public function request() { + if ($this->realSubject === null) { + $this->realSubject = new RealSubject(); + } + + $this->beforeRequest(); + $this->realSubject->request(); + $this->afterRequest(); + } + + private function beforeRequest() { + echo "Proxy: Avant la requête.\n"; + } + + private function afterRequest() { + echo "Proxy: Après la requête.\n"; + } +} + +// Utilisation du pattern Proxy +$proxy = new Proxy(); +$proxy->request(); +``` - Decorator : permet d'ajouter des fonctionnalités supplémentaires à un objet de manière dynamique. ```php interface Shape { @@ -587,7 +806,163 @@ class BasketballGame extends Game { } ``` - Command : Ce pattern encapsule une demande en tant qu'objet, ce qui permet de paramétrer les clients avec différentes demandes, de les mettre en file d'attente, de les enregistrer et de les annuler. +```php +// Commande abstraite +interface Command { + public function execute(); +} + +// Commande concrète +class ConcreteCommand implements Command { + private $receiver; + + public function __construct(Receiver $receiver) { + $this->receiver = $receiver; + } + + public function execute() { + $this->receiver->action(); + } +} + +// Récepteur +class Receiver { + private $name; + + public function __construct($name) { + $this->name = $name; + } + + public function action() { + echo "Action effectuée par le récepteur " . $this->name . "\n"; + } +} + +// Invocateur +class Invoker { + private $command; + + public function setCommand(Command $command) { + $this->command = $command; + } + + public function executeCommand() { + $this->command->execute(); + } +} + +// Utilisation du pattern Command +$receiver = new Receiver("Récepteur"); +$command = new ConcreteCommand($receiver); +$invoker = new Invoker(); +$invoker->setCommand($command); +$invoker->executeCommand(); + +``` - Iterator : Ce pattern fournit un moyen d'accéder séquentiellement aux éléments d'une collection sans exposer la structure interne de la collection. Il permet d'itérer de manière transparente sur les éléments d'une collection. +```php +// Agrégat +interface Aggregator { + public function getIterator(): Iterator; +} + +// Itérateur +interface Iterator { + public function hasNext(): bool; + public function next(); +} + +// Implémentation concrète de l'agrégat +class ConcreteAggregator implements Aggregator { + private $items = []; + + public function addItem($item) { + $this->items[] = $item; + } + + public function getIterator(): Iterator { + return new ConcreteIterator($this->items); + } +} + +// Implémentation concrète de l'itérateur +class ConcreteIterator implements Iterator { + private $items; + private $position = 0; + + public function __construct($items) { + $this->items = $items; + } + + public function hasNext(): bool { + return $this->position < count($this->items); + } + + public function next() { + if ($this->hasNext()) { + $item = $this->items[$this->position]; + $this->position++; + return $item; + } + } +} + +// Utilisation du pattern Iterator +$aggregator = new ConcreteAggregator(); +$aggregator->addItem("Item 1"); +$aggregator->addItem("Item 2"); +$aggregator->addItem("Item 3"); + +$iterator = $aggregator->getIterator(); +while ($iterator->hasNext()) { + echo $iterator->next() . "\n"; +} +``` - State : Ce pattern permet à un objet de modifier son comportement interne lorsqu'il change d'état. Il encapsule chaque état possible dans une classe distincte et permet au contexte d'alterner entre les états de manière transparente. +```php +// Contexte +class Context { + private $state; + + public function __construct(State $state) { + $this->state = $state; + } + + public function setState(State $state) { + $this->state = $state; + } + + public function request() { + $this->state->handle($this); + } +} + +// État abstrait +interface State { + public function handle(Context $context); +} + +// Implémentation concrète de l'état +class ConcreteStateA implements State { + public function handle(Context $context) { + echo "Traitement spécifique de l'État A.\n"; + $context->setState(new ConcreteStateB()); + } +} + +// Implémentation concrète de l'état +class ConcreteStateB implements State { + public function handle(Context $context) { + echo "Traitement spécifique de l'État B.\n"; + $context->setState(new ConcreteStateA()); + } +} + +// Utilisation du pattern State +$context = new Context(new ConcreteStateA()); +$context->request(); // Appelle le traitement spécifique de l'État A +$context->request(); // Appelle le traitement spécifique de l'État B +$context->request(); // Appelle le traitement spécifique de l'État A +``` Ces patterns comportementaux offrent des solutions génériques pour gérer les interactions et les comportements des objets dans un système. Ils améliorent la flexibilité, la réutilisabilité et la maintenabilité du code en promouvant une meilleure séparation des responsabilités et une modularité accrue. \ No newline at end of file