Composition ou héritage
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 56 sur 91.
Dans le chapitre précédent, tu as appris que les traits fournissent une capacité « has-a », tandis que l’héritage établit une relation « is-a ». La composition approfondit le concept « has-a » en construisant des objets complexes à partir d’objets plus simples, en les stockant comme propriétés plutôt qu’en héritant d’eux.
Avec l’héritage, une Car peut étendre Vehicle. Avec la composition, une Car contient un objet Engine :
<?php
class Engine {
public function start(): string {
return "Engine started";
}
}
class Car {
private Engine $engine;
public function __construct() {
$this->engine = new Engine();
}
public function start(): string {
return $this->engine->start();
}
}
$car = new Car();
echo $car->start();
Sortie :
Engine startedLa classe Car n’hérite pas de Engine : elle en possède un. Cette approche offre des avantages considérables : tu peux remplacer le moteur par une autre implémentation, les classes restent faiblement couplées et tu évites les hiérarchies rigides que crée l’héritage profond.
Une recommandation courante en POO est de « préférer la composition à l’héritage ». L’héritage fonctionne bien pour les véritables hiérarchies de types (un Dog est réellement un Animal), mais la composition est particulièrement adaptée lorsque vous assemblez des fonctionnalités à partir de parties indépendantes. Vous pouvez combiner plusieurs objets, les remplacer à l’exécution et tester les composants de manière isolée.
La prochaine leçon explore l’injection de dépendances, qui s’appuie directement sur la composition en contrôlant la manière dont les objets reçoivent leurs dépendances.
Défi
FacileConstruisons un système informatique en utilisant la composition, où un Computer est assemblé à partir d’objets composants distincts plutôt que d’en hériter. Cela montre comment la composition vous permet de construire des objets complexes à partir de parties plus simples et indépendantes.
Vous organiserez votre code sur trois fichiers :
Processor.php: créez une classeProcessorqui représente un CPU. Utilisez la promotion des propriétés du constructeur pour définir un$modelprivé (chaîne de caractères) et un$coresprivé (entier). Ajoutez une méthodegetSpecs()qui renvoie"[model] ([cores] cores)".Memory.php: créez une classeMemoryqui représente la RAM. Utilisez la promotion des propriétés du constructeur pour définir un$sizeprivé (entier représentant des Go). Ajoutez une méthodegetCapacity()qui renvoie"[size]GB RAM".main.php: incluez les deux fichiers de composants et créez une classeComputerqui utilise la composition. La classeComputerdoit :- Stocker un objet
Processoret un objetMemoryen tant que propriétés privées - Accepter un modèle de processeur, un nombre de cœurs et une capacité mémoire dans son constructeur
- Créer les objets composants en interne lors de la construction
- Disposer d’une méthode
describe()qui renvoie"Computer with [processor specs] and [memory capacity]"
Vous recevrez trois entrées : un modèle de processeur, un nombre de cœurs et une capacité mémoire en Go. Créez un
Computeravec ces spécifications et affichez le résultat de l’appel àdescribe().- Stocker un objet
Remarquez que Computer n’étend ni Processor ni Memory. Il les contient. Cette relation de type « possède-un », obtenue grâce à la composition, permet à chaque composant de rester indépendant et réutilisable, tout en permettant à Computer de déléguer certaines tâches à ses composants lorsque cela est nécessaire.
Essayez vous-même
<?php
require_once 'Processor.php';
require_once 'Memory.php';
class Computer
{
// TODO: Définir des propriétés privées pour stocker les objets Processor et Memory
// TODO: Le constructeur doit accepter le modèle du processeur, le nombre de cœurs et la taille de la mémoire
// et créer les objets composants en interne
public function __construct()
{
// TODO: Créer les objets Processor et Memory et les stocker
}
// TODO: Implémenter la méthode describe() qui retourne
// "Computer with [processor specs] and [memory capacity]"
public function describe(): string
{
// TODO: Déléguer aux objets composants et retourner la chaîne formatée
}
}
// Lire l'entrée
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));
// TODO: Créer un Computer avec les spécifications données et afficher le résultat de describe()
?>Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition des méthodesLe mot-clé finalClasses abstraitesRécapitulatif – Hiérarchie des employés7Encapsulation
Public, Protected, PrivateModificateurs d’accès en profondeurAccesseurs et mutateursDissimulation de l’informationPromotion des constructeurs (8.0)Récapitulatif – Système de fiches étudiant10Concepts avancés de la POO
Composition ou héritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibres (PHP 8.1)Approfondissement du clonage d’objetsGénérateurs et itérateurs13Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron Dépôt2Espaces de noms et chargement automatique
Introduction aux espaces de nomsLe mot-clé useNorme de chargement automatique PSR-4Autoloader de ComposerRécapitulatif - Projet organisé5Interfaces et contrats
Introduction aux interfacesImplémentation des interfacesImplémentation de plusieurs interfacesInterface ou classe abstraiteIndication de type avec les interfacesRécapitulatif - Calculateur de formes8Méthodes magiques
Introduction aux méthodes magiques__toString et __debugInfo__get, __set, __isset, __unset__call et __callStatic__clone et clonage d’objets__serialize et __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d’instance vs statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés en lecture seule (PHP 8.1)Récapitulatif - Gestionnaire de comptes bancaires6Polymorphisme
Révision de la redéfinition des méthodesPolymorphisme via les interfacesAnnotations de type et types unionLiaison statique tardiveRécapitulatif - Processeur de paiements9Traits
Introduction aux traitsUtilisation de plusieurs traitsRésolution des conflits entre traitsMéthodes abstraites dans les traitsTraits par rapport à l’héritage12Patrons de conception – Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur PHP en ligne