Il Facade Pattern (o façade pattern) è un pattern di progettazione software comunemente usato nella programmazione orientata agli oggetti. Il nome è per analogia con una facciata architettonica.
Una facciata è un oggetto che fornisce un’interfaccia semplificata ad un corpo di codice più grande, come una libreria di classi. Una facciata può:
- rendere una libreria software più facile da usare, capire e testare, poiché la facciata ha metodi convenienti per compiti comuni;
- rendere la libreria più leggibile, per lo stesso motivo;
- ridurre le dipendenze del codice esterno dal funzionamento interno di una libreria, poiché la maggior parte del codice usa la facciata, permettendo così una maggiore flessibilità nello sviluppo del sistema;
- avvolgere un insieme di API mal progettato con una singola API ben progettata.
Il design pattern Facade è spesso usato quando un sistema è molto complesso o difficile da capire perché il sistema ha un gran numero di classi interdipendenti o il suo codice sorgente non è disponibile. Questo pattern nasconde le complessità del sistema più grande e fornisce un’interfaccia più semplice al client. Tipicamente coinvolge una singola classe wrapper che contiene un insieme di membri richiesti dal client. Questi membri accedono al sistema per conto del client facade e nascondono i dettagli dell’implementazione.
Usage
Un Facade è usato quando si desidera un’interfaccia più facile o più semplice per un oggetto sottostante. In alternativa, un adattatore può essere usato quando il wrapper deve rispettare una particolare interfaccia e deve supportare un comportamento polimorfico. Un decoratore rende possibile aggiungere o alterare il comportamento di un’interfaccia a run-time.
Pattern | Intent |
---|---|
Adapter | Converte un’interfaccia in un’altra in modo che corrisponda a ciò che il client si aspetta |
Decorator | Aggiunge dinamicamente responsabilità all’interfaccia avvolgendo il codice originale |
Facade | Fornisce un’interfaccia semplificata |
Il modello facade è tipicamente usato quando:
- è richiesta un’interfaccia semplice per accedere ad un sistema complesso;
- le astrazioni e le implementazioni di un sottosistema sono strettamente accoppiate;
- necessitano di un punto di ingresso per ogni livello di software stratificato; o
- un sistema è molto complesso o difficile da capire.
Struttura
Facciata: La classe facade astrae i pacchetti 1, 2 e 3 dal resto dell’applicazione.Clients: Gli oggetti usano il Facade Pattern per accedere alle risorse dei Pacchetti.
Esempio
Questo è un esempio astratto di come un cliente (“tu”) interagisce con una facciata (il “computer”) di un sistema complesso (parti interne del computer, come CPU e HardDrive).
/* Complex parts */class CPU { freeze() { /* code here */ } jump(position) { /* code here */ } execute() { /* code here */ }}class Memory { load(position, data) { /* code here */ }}class HardDrive { read(lba, size) { /* code here */ }}/* Facade */class ComputerFacade { constructor() { this.processor = new CPU(); this.ram = new Memory(); this.hd = new HardDrive(); } start() { this.processor.freeze(); this.ram.load(this.BOOT_ADDRESS, this.hd.read(this.BOOT_SECTOR, this.SECTOR_SIZE)); this.processor.jump(this.BOOT_ADDRESS); this.processor.execute(); }}/* Client */let computer = new ComputerFacade();computer.start();