Patrons structurels : adaptateur, décorateur, façade
Composez des objets et simplifiez les interfaces grâce aux patrons structurels.
Patrons structurels : adaptateur, décorateur, façade est une leçon PHP Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage PHP Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours PHP Academy comprend 4 leçons au total.
Composer des objets
Les patrons structurels décrivent comment composer des classes et des objets en structures plus grandes tout en les gardant flexibles. Nous abordons trois patrons essentiels :
- Adaptateur — rendre utilisable une interface incompatible.
- Décorateur — ajouter un comportement sans créer de sous-classe.
- Façade — présenter une interface simple devant un sous-système complexe.
Adaptateur : le problème
Vous dépendez d’une interface PaymentGateway, mais un SDK tiers expose chargeCard($amountInCents) avec une forme différente. Appeler directement le SDK diffuse son API dans tout le code. Ci-dessous, les deux interfaces sont clairement incompatibles : c’est précisément ce décalage que résout un adaptateur.
<?php
// What our app wants to depend on
interface PaymentGateway { public function pay(float $dollars): string; }
// What the vendor actually gives us (cents, array result)
final class StripeSdk {
public function chargeCard(int $cents): array {
return ['id' => 'ch_1', 'amount' => $cents];
}
}
// dollars vs cents, string vs array -> shapes don't line up
var_dump((new StripeSdk())->chargeCard(2000));
Adaptateur dans le code
L’adaptateur contient l’adapté et implémente votre interface cible, en convertissant les arguments et les valeurs de retour. Le code de votre application reste propre et indépendant du fournisseur.
<?php
interface PaymentGateway { public function pay(float $dollars): string; }
// Third-party SDK with an incompatible API
final class StripeSdk {
public function chargeCard(int $cents): array {
return ['id' => 'ch_1', 'amount' => $cents];
}
}
final class StripeAdapter implements PaymentGateway {
public function __construct(private StripeSdk $sdk) {}
public function pay(float $dollars): string {
$res = $this->sdk->chargeCard((int) round($dollars * 100));
return "charged {$res['amount']}c -> {$res['id']}";
}
}
echo (new StripeAdapter(new StripeSdk()))->pay(20.0), PHP_EOL;
Décorateur : l’idée
Un Décorateur enveloppe un objet qui partage son interface et ajoute un comportement avant ou après la délégation. Contrairement à l’héritage, les décorateurs s’empilent à l’exécution, ce qui permet de combiner les fonctionnalités dans n’importe quel ordre sans multiplier les classes. Voici la structure minimale : une enveloppe qui implémente la même interface et contient l’instance interne.
<?php
interface Coffee { public function cost(): float; }
final class Espresso implements Coffee {
public function cost(): float { return 2.0; }
}
final class WithMilk implements Coffee {
public function __construct(private Coffee $inner) {}
public function cost(): float { return $this->inner->cost() + 0.5; }
}
echo (new WithMilk(new Espresso()))->cost(), PHP_EOL; // 2.5
Décorateur dans le code
Chaque décorateur implémente la même interface et contient une instance interne. Ici, nous enveloppons une source de données avec une mise en cache et une journalisation, en les composant librement.
<?php
interface DataSource { public function read(): string; }
final class FileSource implements DataSource {
public function read(): string { return 'raw-data'; }
}
final class UpperCaseDecorator implements DataSource {
public function __construct(private DataSource $inner) {}
public function read(): string { return strtoupper($this->inner->read()); }
}
final class ExclaimDecorator implements DataSource {
public function __construct(private DataSource $inner) {}
public function read(): string { return $this->inner->read() . '!!!'; }
}
$src = new ExclaimDecorator(new UpperCaseDecorator(new FileSource()));
echo $src->read(), PHP_EOL; // RAW-DATA!!!
Les décorateurs en pratique
Les intergiciels PSR-7/PSR-15 appliquent essentiellement le patron du décorateur à la gestion HTTP : chaque intergiciel enveloppe le suivant et ajoute l’authentification, la journalisation ou la mise en cache autour de la requête et de la réponse. Les enveloppes de flux et les couches de cache PSR-6/16 utilisent également souvent la décoration. La caractéristique essentielle est la suivante : l’enveloppe peut se substituer à l’élément qu’elle enveloppe.
Décorateur ou héritage
L’héritage fixe le comportement à la compilation et n’autorise qu’une seule classe de base. La décoration est dynamique et composable. Choisissez les décorateurs lorsque :
- les combinaisons de fonctionnalités facultatives se multiplient ;
- le comportement doit être ajouté ou retiré à l’exécution ;
- vous devez étendre une classe
finalou tierce dont vous ne pouvez pas créer de sous-classe.
Façade : l’idée
Une Façade fournit un point d’entrée unique et simplifié vers un sous-système complexe composé de nombreuses classes. Elle ne masque pas le sous-système (vous pouvez toujours y accéder directement), mais offre une interface de programmation pratique de haut niveau pour le cas courant. Comparez les nombreuses opérations détaillées du sous-système ci-dessous avec l’appel en une ligne à la façade dans la scène suivante.
<?php
// Without a facade, the client wires every step itself
final class Cpu { public function boot(): string { return 'cpu '; } }
final class Disk { public function load(): string { return 'disk '; } }
final class Ram { public function check(): string { return 'ram'; } }
$out = (new Cpu())->boot() . (new Disk())->load() . (new Ram())->check();
echo $out, PHP_EOL; // cpu disk ram
Façade dans le code
La façade orchestre plusieurs collaborateurs derrière une seule méthode. Les clients appellent place() au lieu de relier eux-mêmes les stocks, les paiements et les expéditions.
<?php
final class Inventory { public function reserve(string $sku): bool { return true; } }
final class Payments { public function charge(float $amt): bool { return true; } }
final class Shipping { public function dispatch(string $sku): string { return 'tracking-99'; } }
final class OrderFacade {
public function __construct(
private Inventory $inv,
private Payments $pay,
private Shipping $ship
) {}
public function place(string $sku, float $amount): string {
if (!$this->inv->reserve($sku)) { return 'out of stock'; }
if (!$this->pay->charge($amount)) { return 'payment failed'; }
return 'shipped: ' . $this->ship->dispatch($sku);
}
}
echo (new OrderFacade(new Inventory(), new Payments(), new Shipping()))
->place('ABC', 49.99), PHP_EOL;
Distinguer les trois patrons
- Adaptateur modifie une interface pour permettre la communication entre deux composants existants ; le comportement reste le même, seule la forme change.
- Décorateur conserve l’interface, mais ajoute un comportement empilable à l’exécution.
- Façade introduit une nouvelle interface plus simple devant de nombreuses classes.
Un moyen simple de les distinguer : l’adaptateur concerne la compatibilité, le décorateur l’amélioration et la façade la simplification.
Remarque sur les façades de Laravel
Les « façades » de Laravel sont un mécanisme de proxy statique reposant sur le conteneur de services, et non le patron Façade de GoF. Elles ont en commun l’objectif de fournir un point d’accès pratique, mais leur implémentation diffère. Ne confondez pas la terminologie du cadre avec le patron structurel lorsque vous raisonnez sur la conception.
Vérification rapide
Identifiez le patron à partir de son intention.
Récapitulatif
Vous avez composé des objets avec trois patrons structurels : Adaptateur pour relier des interfaces incompatibles (par exemple, un SDK fournisseur), Décorateur pour empiler des comportements à l’exécution (à la base des intergiciels PSR-15) et Façade pour présenter une interface simple devant un sous-système complexe. Chacun réduit le couplage, afin que votre code résiste à la dépendance à un fournisseur et à la prolifération des fonctionnalités.
Questions Fréquemment Posées
La leçon « Patrons structurels : adaptateur, décorateur, façade » est-elle gratuite ?
Oui — le texte complet de « Patrons structurels : adaptateur, décorateur, façade » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours PHP Academy, passe à CoddyKit PRO. Le cours PHP Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Patrons structurels : adaptateur, décorateur, façade » ?
Composez des objets et simplifiez les interfaces grâce aux patrons structurels. Tu pratiques PHP Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer PHP Academy ?
Aucune expérience préalable n'est requise. PHP Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Patrons structurels : adaptateur, décorateur, façade » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon PHP Academy ?
Oui. Chaque leçon PHP Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Les principes SOLID en pratique
- Patrons de création : fabrique, constructeur, singleton
- Patrons structurels : adaptateur, décorateur, façade
- Patrons comportementaux : stratégie, observateur, commande