Design patterns: Facade
Il Facade Pattern fornisce un’interfaccia semplificata per un insieme di interfacce in un sistema complesso, rendendo più facile l’uso delle funzionalità del sistema. È particolarmente utile quando si desidera semplificare l’interazione con un sistema o una libreria complessa.
Caratteristiche del Facade Pattern
- Interfaccia semplificata: Il Facade Pattern fornisce un’interfaccia semplificata a un sistema complesso o a un insieme di classi, rendendo più facile l’interazione con questi componenti senza dover comprendere i dettagli interni.
- Isolamento dal Sistema sottostante: Consente di isolare il client dalle complessità del sistema sottostante, riducendo la dipendenza e migliorando la manutenibilità. I client non devono conoscere le classi specifiche e le loro interazioni.
- Facilitazione dell’utilizzo: Rende più semplice e intuitivo utilizzare un sistema complesso, riducendo la curva di apprendimento per gli sviluppatori e migliorando l’esperienza dell’utente.
- Supporto per il riuso del codice: Può riunire classi e funzionalità esistenti in un’unica interfaccia, facilitando il riuso del codice e semplificando l’integrazione di nuove funzionalità.
- Facilitazione delle modifiche: Consente di apportare modifiche al sistema sottostante senza influenzare il client. Se il sistema viene aggiornato, il client può continuare a utilizzare la facciata senza modifiche.
Esempio in PHP:
Immagina di avere un sistema di gestione di un cinema che gestisce diverse operazioni come la gestione di film, la vendita di biglietti e la gestione degli utenti. Un Facade può semplificare queste interazioni per l’utente finale.
// Sottosistema: Gestione dei Film
class Movie {
private $title;
private $duration; // in minuti
public function __construct($title, $duration) {
$this->title = $title;
$this->duration = $duration;
}
public function getTitle() {
return $this->title;
}
public function getDuration() {
return $this->duration;
}
}
// Sottosistema: Gestione dei Biglietti
class Ticket {
private $movie;
private $seatNumber;
public function __construct(Movie $movie, $seatNumber) {
$this->movie = $movie;
$this->seatNumber = $seatNumber;
}
public function getDetails() {
return "Biglietto per il film '{$this->movie->getTitle()}' in posto {$this->seatNumber}.";
}
}
// Sottosistema: Gestione degli Utenti
class User {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
// Facade: Sistema di Cinema
class CinemaFacade {
private $movies = [];
private $users = [];
public function addMovie($title, $duration) {
$this->movies[] = new Movie($title, $duration);
}
public function addUser($name) {
$this->users[] = new User($name);
}
public function bookTicket($userName, $movieTitle, $seatNumber) {
// Trova l'utente
$user = null;
foreach ($this->users as $u) {
if ($u->getName() == $userName) {
$user = $u;
break;
}
}
// Trova il film
$movie = null;
foreach ($this->movies as $m) {
if ($m->getTitle() == $movieTitle) {
$movie = $m;
break;
}
}
// Se l'utente e il film esistono, prenota il biglietto
if ($user && $movie) {
$ticket = new Ticket($movie, $seatNumber);
return $ticket->getDetails();
} else {
return "Prenotazione fallita: utente o film non trovati.";
}
}
}
// Utilizzo della Facade
$cinema = new CinemaFacade();
$cinema->addMovie("Inception", 148);
$cinema->addMovie("The Matrix", 136);
$cinema->addUser("Alice");
$cinema->addUser("Bob");
// Prenotazione di un biglietto
echo $cinema->bookTicket("Alice", "Inception", "A1") . "\n";
// Output: Biglietto per il film 'Inception' in posto A1.
echo $cinema->bookTicket("Bob", "The Matrix", "B2") . "\n";
// Output: Biglietto per il film 'The Matrix' in posto B2.
echo $cinema->bookTicket("Charlie", "Inception", "C3") . "\n";
// Output: Prenotazione fallita: utente o film non trovati.