Menu
Coddy logo textTech

Composizione vs ereditarietà

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 56 di 91.

Nel capitolo precedente hai imparato che i trait forniscono una capacità «ha un» mentre l'ereditarietà stabilisce una relazione «è un». La composizione sviluppa ulteriormente il concetto «ha un», costruendo oggetti complessi a partire da oggetti più semplici e memorizzandoli come proprietà invece di ereditarli.

Con l'ereditarietà, una Car potrebbe estendere Vehicle. Con la composizione, una Car contiene un oggetto 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();

Output:

Engine started

La classe Car non eredita da Engine: ne possiede una. Questo approccio offre vantaggi significativi: puoi sostituire il motore con un’implementazione diversa, le classi rimangono debolmente accoppiate e puoi evitare le rigide gerarchie create da un’ereditarietà profonda.

Una linea guida comune nella programmazione orientata agli oggetti è "preferire la composizione all'ereditarietà." L'ereditarietà funziona bene per le gerarchie di tipi autentiche (un Dog è davvero un Animal), ma la composizione dà il meglio quando assembli funzionalità a partire da parti indipendenti. Puoi combinare più oggetti, sostituirli durante l'esecuzione e testare i componenti in modo isolato.

La prossima lezione approfondisce l'iniezione delle dipendenze, che si basa direttamente sulla composizione controllando il modo in cui gli oggetti ricevono le proprie dipendenze.

challenge icon

Sfida

Facile

Costruiamo un sistema informatico usando la composizione, in cui un Computer è assemblato a partire da oggetti componente separati invece di ereditare da essi. Questo dimostra come la composizione consenta di creare oggetti complessi a partire da parti più semplici e indipendenti.

Organizzerai il codice in tre file:

  • Processor.php: crea una classe Processor che rappresenta una CPU. Usa la promozione dei parametri del costruttore per definire un $model privato (stringa) e un $cores privato (intero). Aggiungi un metodo getSpecs() che restituisce "[model] ([cores] cores)".
  • Memory.php: crea una classe Memory che rappresenta la RAM. Usa la promozione dei parametri del costruttore per definire un $size privato (intero che rappresenta i GB). Aggiungi un metodo getCapacity() che restituisce "[size]GB RAM".
  • main.php: includi entrambi i file dei componenti e crea una classe Computer che usa la composizione. Computer dovrà:
    • Memorizzare un oggetto Processor e un oggetto Memory come proprietà private
    • Accettare nel costruttore un modello di processore, il numero di core e la dimensione della memoria
    • Creare internamente gli oggetti componente durante la costruzione
    • Avere un metodo describe() che restituisce "Computer with [processor specs] and [memory capacity]"

    Riceverai tre input: un modello di processore, un numero di core e una dimensione della memoria in GB. Crea un Computer con queste specifiche e stampa il risultato della chiamata a describe().

Nota che Computer non estende Processor o Memory. Li contiene. Questa relazione «ha un» tramite la composizione mantiene ogni componente indipendente e riutilizzabile, consentendo al contempo a Computer di delegare alle sue parti quando necessario.

Provalo tu

<?php
require_once 'Processor.php';
require_once 'Memory.php';

class Computer
{
    // TODO: Definire proprietà private per memorizzare gli oggetti Processor e Memory

    // TODO: Il costruttore deve accettare il modello del processore, il numero di core e la dimensione della memoria
    // e creare internamente gli oggetti dei componenti
    public function __construct()
    {
        // TODO: Creare gli oggetti Processor e Memory e memorizzarli
    }

    // TODO: Implementare il metodo describe() che restituisce
    // "Computer with [processor specs] and [memory capacity]"
    public function describe(): string
    {
        // TODO: Delegare agli oggetti dei componenti e restituire una stringa formattata
    }
}

// Leggere l'input
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));

// TODO: Creare un Computer con le specifiche fornite e stampare il risultato di describe()

?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online