Design patterns: Composite
Il Composite Pattern permette di trattare gli oggetti singoli e le composizioni di oggetti in modo uniforme. Questo pattern è utile quando si ha una struttura gerarchica dove singoli oggetti e gruppi di oggetti devono essere trattati nello stesso modo.
Caratteristiche del Composite pattern
- Struttura ad albero: Il Composite Pattern consente di creare una struttura ad albero composta da oggetti singoli (foglie) e oggetti composti (nodi). Questa struttura facilita la rappresentazione gerarchica di oggetti.
- Trattamento uniforme: Permette di trattare in modo uniforme gli oggetti singoli e i gruppi di oggetti. I client possono interagire con entrambi gli oggetti usando la stessa interfaccia, semplificando il codice client.
- Flessibilità: Consente di aggiungere nuovi componenti sia a livello di oggetto singolo che di gruppo senza modificare il codice esistente. Questo favorisce la manutenibilità e l’estendibilità.
- Semplificazione della gestione degli Oggetti: Riduce la complessità della gestione degli oggetti, permettendo ai client di lavorare con un’interfaccia semplice per costruire e manipolare strutture complesse.
- Ricorsività: Il Composite Pattern è spesso ricorsivo, consentendo di costruire strutture di oggetti nidificati. I metodi definiti nell’interfaccia possono essere chiamati ricorsivamente su tutti i livelli della struttura.
Esempio in PHP:
Immagina di voler rappresentare una struttura gerarchica di cartelle e file in un file system. Le cartelle possono contenere altri file o cartelle. Il Composite Pattern permette di trattare sia i file che le cartelle come oggetti “compositi”.
// Interfaccia componente comune
interface FileSystemComponent {
public function showDetails();
}
// Oggetto foglia: il file
class File implements FileSystemComponent {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function showDetails() {
echo "File: $this->name\n";
}
}
// Oggetto composto: la cartella
class Folder implements FileSystemComponent {
private $name;
private $components = [];
public function __construct($name) {
$this->name = $name;
}
public function addComponent(FileSystemComponent $component) {
$this->components[] = $component;
}
public function showDetails() {
echo "Folder: $this->name\n";
foreach ($this->components as $component) {
$component->showDetails(); // Trattiamo file e cartelle nello stesso modo
}
}
}
// Utilizzo
$file1 = new File("file1.txt");
$file2 = new File("file2.txt");
$file3 = new File("file3.txt");
$folder1 = new Folder("folder1");
$folder2 = new Folder("folder2");
$folder1->addComponent($file1);
$folder1->addComponent($file2);
$folder2->addComponent($file3);
$folder2->addComponent($folder1);
$folder2->showDetails();
/*
Output:
Folder: folder2
File: file3.txt
Folder: folder1
File: file1.txt
File: file2.txt
*/