Introduzione
Nell’ingegneria del software, un Design Pattern descrive una soluzione consolidata ai problemi più comunemente riscontrati nel software design. Rappresenta le migliori pratiche sviluppate in un lungo periodo attraverso tentativi ed errori da parte di sviluppatori di software esperti.
Design Patterns ha guadagnato popolarità dopo che il libro Design Patterns: Elements of Reusable Object-Oriented Software è stato pubblicato nel 1994 da Erich Gamma , John Vlissides, Ralph Johnson e Richard Helm (noto anche come Gang of Four o GoF).
In questo articolo esploreremo i modelli di design creativi e i loro tipi. Vedremo anche alcuni esempi di codice e discutere le situazioni in cui questi pattern si adattano al nostro design.
Creational Design Patterns
Creational Design Patterns riguarda il modo in cui gli oggetti vengono creati . Riducono le complessità e l’instabilità creando oggetti in modo controllato.
Il nuovo operatore è spesso considerato dannoso in quanto disperde gli oggetti in tutta l’applicazione. Nel tempo può diventare difficile modificare un’implementazione perché le classi diventano strettamente collegate.
I modelli di progettazione creazionali risolvono questo problema disaccoppiando completamente il client dal processo di inizializzazione effettivo.
In questo articolo , discuteremo quattro tipi di Creational Design Pattern:
- Singleton – Assicura che esista al massimo una sola istanza di un oggetto in tutta l’applicazione
- Factory Method – Crea oggetti di diverse classi correlate senza specificare l’oggetto esatto da creare
- Fabbrica astratta: crea famiglie di oggetti dipendenti correlati
- Builder – Costruisce oggetti complessi utilizzando un approccio graduale
Discutiamo ora ciascuno di questi pattern in dettaglio.
Singleton Design Pattern
Il Singleton Design Pattern mira a mantenere un controllo sull’inizializzazione di oggetti di una particolare classe assicurando che esista solo un’istanza dell’oggetto in tutta la Java Virtual Machine.
Una classe Singleton fornisce anche un punto di accesso globale univoco all’oggetto in modo che ogni successiva chiamata al punto di accesso restituisca solo quel particolare oggetto.
3.1. Esempio di pattern Singleton
Sebbene il pattern Singleton sia stato introdotto da GoF, l’implementazione originale è nota per essere problematica negli scenari multithread.
Quindi qui, noi ” seguiremo un approccio più ottimale che fa uso di una classe interna statica:
Qui abbiamo creato una classe interna statica che contiene l’istanza della classe Singleton. Crea l’istanza solo quando qualcuno chiama il metodo getInstance () e non quando viene caricata la classe esterna.
Questo è un approccio ampiamente utilizzato per una classe Singleton in quanto non richiede sincronizzazione, è thread-safe , impone l’inizializzazione pigra e ha un boilerplate relativamente inferiore.
Inoltre, si noti che il costruttore ha il modificatore di accesso privato. Questo è un requisito per creare un Singleton poiché un costruttore pubblico significherebbe che chiunque potrebbe accedervi e iniziare a creare nuove istanze.
Ricorda, questa non è l’implementazione GoF originale. Per la versione originale, visita questo articolo di Baeldung collegato su Singleton in Java.
3.2. Quando utilizzare Singleton Design Pattern
- Per risorse costose da creare (come database oggetti di connessione)
- È buona norma mantenere tutti i logger come Singleton, il che aumenta le prestazioni
- Classi che forniscono accesso alle impostazioni di configurazione per l’applicazione
- Classi che contengono risorse a cui si accede in modalità condivisa
Factory Method Design Pattern
Factory Design Pattern o Factory Method Design Pattern è uno dei modelli di progettazione più utilizzati in Java.
Secondo GoF, questo modello “definisce un’interfaccia per la creazione di un oggetto, ma lascia che le sottoclassi decidano quale classe installare tiate. Il metodo Factory consente a una classe di differire l’istanziazione a sottoclassi “.
Questo modello delega la responsabilità di inizializzare una classe dal client a una particolare classe factory creando un tipo di costruttore virtuale.
Per raggiungere questo obiettivo, ci affidiamo a una fabbrica che ci fornisce gli oggetti, nascondendo i dettagli effettivi di implementazione. Si accede agli oggetti creati utilizzando un’interfaccia comune.
4.1. Factory Method Design Pattern Example
In questo esempio, creeremo un’interfaccia Polygon che sarà implementata da diverse classi concrete. Una PolygonFactory sarà usata per recuperare oggetti da questa famiglia :
Creiamo prima l’interfaccia Polygon:
Avanti, creeremo alcune implementazioni come Square, Triangle, ecc. che implementano questa interfaccia e restituiscono un oggetto di tipo Polygon.
Ora possiamo creare una fabbrica che prende il numero di lati come argomento e restituisce l’implementazione appropriata di questa interfaccia:
Nota come il cliente può fare affidamento su questa fabbrica per darci un Polygon appropriato, senza dover inizializzare direttamente l’oggetto.
4.2. Quando utilizzare Factory Method Design Pattern
- Quando si prevede che l’implementazione di un’interfaccia o di una classe astratta cambi frequentemente
- Quando l’implementazione corrente non può accogliere comodamente nuove modifiche
- Quando il processo di inizializzazione è relativamente semplice e il costruttore richiede solo una manciata di parametri
Abstract Factory Design Pattern
Nella sezione precedente, abbiamo visto come il design pattern Factory Method potrebbe essere utilizzato per creare oggetti relativi a una singola famiglia.
Al contrario, viene utilizzato il Abstract Factory Design Pattern per creare famiglie di oggetti correlati o dipendenti. A volte viene anche chiamata fabbrica di fabbriche.
Per una spiegazione dettagliata, guarda il nostro tutorial sulla Fabbrica astratta.
Builder Design Pattern
Il Builder Design Pattern è un altro pattern creativo progettato per gestire la costruzione di oggetti relativamente complessi.
Quando la complessità della creazione di oggetti aumenta, il Builder pattern può separare il processo di istanziazione utilizzando un altro object (un builder) per costruire l’oggetto.
Questo builder può quindi essere utilizzato per creare molte altre rappresentazioni simili utilizzando un semplice approccio passo-passo.
6.1. Builder Pattern Esempio
Il Builder Design Pattern originale introdotto da GoF si concentra sull’astrazione ed è molto buono quando si tratta di oggetti complessi, tuttavia, il design è un po ‘complicato.
Joshua Bloch, nel suo libro Effective Java, ha introdotto una versione migliorata del pattern builder che è pulita, altamente leggibile (perché fa uso di design fluente) e facile da usare dal punto di vista del cliente. In questo esempio, discuteremo quella versione.
Questo esempio ha solo una classe, BankAccount che contiene un generatore come classe interna statica:
Nota che tutti i modificatori di accesso sui campi sono dichiarati privati poiché non vogliamo che gli oggetti esterni accedano direttamente.
Anche il costruttore è privato in modo che solo il Builder assegnato a questo la classe può accedervi. Tutte le proprietà impostate nel costruttore vengono estratte dall’oggetto builder che forniamo come argomento.
Abbiamo definito BankAccountBuilder in una classe interna statica:
Notare che abbiamo dichiarato lo stesso insieme di campi che contiene la classe esterna. Tutti i campi obbligatori sono richiesti come argomenti per il costruttore della classe interna mentre i restanti campi opzionali possono essere specificati utilizzando i metodi setter.
Questa implementazione supporta anche l’approccio di progettazione fluente facendo in modo che i metodi setter restituiscano il builder oggetto.
Infine, il metodo build chiama il costruttore privato della classe esterna e passa se stesso come argomento. Il BankAccount restituito verrà istanziato con i parametri impostati da BankAccountBuilder.
Vediamo un rapido esempio del pattern builder in azione:
6.2. Quando utilizzare il pattern Builder
- Quando il processo coinvolto nella creazione di un oggetto è estremamente complesso, con molti parametri obbligatori e facoltativi
- Quando un l’aumento del numero di parametri del costruttore porta a un ampio elenco di costruttori
- Quando il cliente si aspetta rappresentazioni diverse per l’oggetto che “è costruito
Conclusione
In questo articolo, abbiamo imparato a conoscere i modelli di progettazione creativa in Java. Abbiamo anche discusso i loro quattro diversi tipi, ad esempio, Singleton, Factory Method, Abstract Factory e Builder Pattern, i loro vantaggi, esempi e quando dovrebbe li usiamo.
Come sempre, gli snippet di codice completi sono disponibili su GitHub.
Inizia con Spring 5 e Spring Boot 2, tramite il corso Learn Spring:
> > GUARDA IL CORSO