Esplora E-book
Categorie
Esplora Audiolibri
Categorie
Esplora Riviste
Categorie
Esplora Documenti
Categorie
Il pattern si definisce come una soluzione architetturale che può risolvere problemi in contesti eterogenei.
C'è stato un gruppo di 4 persone, la cosiddetta GOF(Gang of Four) che ha creato 23 pattern in base a
differenti contesti e in base alla circostanza d'uso.
3 sono i tipi di Pattern fondamentali:
Creational Patterns-Pattern creazionali: propongono soluzioni per creare oggetti
Structural Patterns-Pattern strutturali: propongono soluzioni per la composizione strutturale di
classi e oggetti
Behavioral Patterns-Pattern comportamentali: propongono soluzioni per gestire il modo in cui
vengono suddivise le responsabilità delle classi e degli oggetti
-Builder(costruttore):
Scopo: Separare la costruzione di un oggetto complesso dalla sua rappresentazione in modo tale
che lo stesso processo di costruzione può creare differenti rappresentazioni
Motivazione: Un’applicazione potrebbe avere bisogno di un meccanismo per la costruzione di
oggetti complessi che è indipendente da quelli che compongono l’oggetto. Definisce un’istanza per
creare un oggetto ma dando la possibilità alle sottoclassi di decidere quali classi istanziare.
Riferimento ai nuovi oggetti creati attraverso un’interfaccia comune
Applicabilità: Un algoritmo per creare un oggetto complesso deve rendere indipendenti le parti per
costruire l’oggetto e per il loro assemblaggio. Il processo di costruzione deve permettere differenti
rappresentazioni per gli oggetti costruiti. Si può usare per:
Casa automobilistica
può costruire auto, biciclette, motociclette e scooter
Builder diventa VehicleBuilder
Applicazione per gli esami studenti
lista e informazioni di esami
differenti utenti di login (admin e user)
Builder fornisce un’interfaccia che fornisce informazioni in base all’utente
-Prototype(prototipo):
Scopo: Specifica il tipo di oggetti da creare usando un’istanza prototipale e creando nuovi oggetti
copiando questi oggetti
Motivazione: Permette ad un oggetto di creare oggetti senza conoscere la loro classe o i dettagli
per crearli
Applicabilità: sistema indipendente da come i suoi prodotti sono creati, composti e rappresentati.
Le classi da istanziare sono specificate a run-time per evitare di scrivere una gerarchia di classi.
E’ più conveniente copiare un’istanza esistente che crearne una nuova. Si usa per:
Game
un labirinto con diversi oggetti visuali
per generare diverse mappe del labirinto
Muri, porte, passaggi, stanze, …
diversi prototipi per i componenti
Vendite
analisi di dati da un database
per ogni analisi sugli stessi dati possiamo clonare le
informazioni estratte dal database
-Iterator:
Scopo: Fornisce un modo per accedere agli elementi di un oggetto aggregato nascondendo i
dettagli di implementazione.
Motivazione: Un oggetto aggregato dovrebbe fornire un metodo per accedere agli elementi senza
esporre la struttura interna
Applicabilità: accedere a contenuti di una collezione senza esporre la sua struttura interna.
Supportare più scorrimenti simultanei di una collezione. Fornire un’interfaccia uniforme per lo
scorrimento di collezioni differenti
-Mediator:
Scopo: Definire un oggetto che incapsula il meccanismo di interazione di oggetti, consentendo il
loro disaccoppiamento in modo da variare facilmente le interazioni tra di loro.
Motivazione: permettere di modificare agilmente le politiche di interazione, poiché le entità
coinvolte devono fare riferimento al loro interno solamente al mediatore
Applicabilità: Un insieme di oggetti comunicano in un modo ben definito ma complesso. Le
interdipendenze non strutturate e difficili da capire. Il riuso di un oggetto è difficile perché si
riferisce e relaziona molti altri oggetti. Un comportamento distribuito tra diverse classi dovrebbe
essere customizzabile senza l’uso di molte sottoclassi. Per esempio si può usare per costruire una
chat
-Memento:
Scopo: L’intento di questo modello è di catturare lo stato interno di un oggetto senza violare
incapsulamento e fornendo così un mezzo per ripristinare l’oggetto allo stato iniziale
quando necessario.
Motivazione: A volte si rende necessaria l’acquisizione dello stato interno di un oggetto in un certo
istante e ripristinare successivamente l’oggetto a quello stato. Il processo è utile in caso di errori,
e.g., calcolatrice che mantiene la lista delle operazioni precedenti
Applicabilità: viene utilizzato quando uno stato di un oggetto deve essere catturato in modo che
possa essere ripristinato a quello stato più tardi. In situazioni in cui il passaggio in modo esplicito
dello stato dell’oggetto violerebbe incapsulamento. Si può anche usare per gestione file
-Template Method:
Scopo: Definire lo scheletro di un algoritmo in un’operazione, rinviando alcuni passi alle sottoclassi
client. Consente alle sottoclassi di ridefinire alcuni passi senza cambiare la struttura dell’algoritmo.
Motivazione: necessità di modificare dinamicamente gli algoritmi utilizzati da un’applicazione
e.g., visite in una struttura ad albero, possibilità di selezionare a tempo di esecuzione una tra le
visite
Applicabilità: quando si vuole implementare la parte invariante di un algoritmo una volta sola e
lasciare che le sottoclassi implementino il comportamento che può variare. Quando il
comportamento comune di più classi può essere fattorizzato in una classe a parte per evitare di
scrivere più volte lo stesso codice. Per avere modo di controllare come le sottoclassi ereditano dalla
superclasse, facendo in modo che i metodi template chiamino dei metodi “gancio” (hook) e
impostarli come unici metodi sovrascrivibili
-Visitor:
Scopo: Rappresentare un’operazione da eseguire sugli elementi di una struttura oggetto. Permette
di definire una nuova operazione senza cambiare le classi degli elementi su cui opera.
Motivazione: separare un algoritmo dalla struttura di oggetti composti a cui è applicato.
Aggiungere nuove operazioni e comportamenti senza dover modificare la struttura stessa.
In collezioni contenere oggetti di tipo diverso
operazioni eseguite su tutti gli elementi di raccolta senza conoscere il tipo
Applicabilità: una struttura di oggetti è costituita da molte classi con interfacce diverse ed è
necessario che l’algoritmo esegua su ogni oggetto un’operazione differente a seconda dalla
classe concreta dell’oggetto stesso. E’ necessario eseguire svariate operazioni indipendenti e
non relazionate tra loro sugli oggetti di una struttura composta, ma non si vuole sovraccaricare le
interfacce delle loro classi. Riunendo le operazioni correlate in ogni Visitor è possibile inserirle nei
-Composite:
Scopo: Comporre oggetti una struttura ad albero per rappresentare gerarchie (whole-part). Il
pattern permette ai client di trattare oggetti singoli e composizioni di oggetti uniformi.
Motivazione: applicazioni hanno bisogno di manipolare una collezione di oggetti primitivi o
composti. Se l’oggetto desiderato è una Leaf, la richiesta è processata direttamente. Se è una
Composite, viene rimandata ai figli cercando di svolgere le operazioni prima
Applicabilità: quando i client dovrebbero ignorare la differenza tra oggetti composti e oggetti
singoli.
Scelta di rifattorizzazione:
durante lo sviluppo i programmatori scoprono che stanno usando più oggetti nello stesso modo e
spesso il codice per gestirli è molto simile
-Decorator:
Scopo: Aggiunge responsabilità addizionali ad un oggetto dinamicamente. Fornisce un’alternativa
flessibile alla costruzione di sottoclassi per estendere delle funzionalità.
Motivazione: consente di aggiungere durante il run-time nuove funzionalità ad oggetti già esistenti:
nuova classe decoratore che “avvolge” l’oggetto originale
-Facade:
Scopo: Fornisce un’interfaccia unificata ad un insieme di interfacce in un sottosistema. Definisce
un’interfaccia di alto livello che permette la facile gestione del sottosistema.
Motivazione: permettere attraverso un’interfaccia più semplice, l’accesso a sottosistemi che
espongono interfacce complesse e molto diverse tra loro, nonché a blocchi di codice complessi
Applicabilità: quando vogliamo fornire un’interfaccia semplice ad un sottosistema complesso.
Sdoppiare client e sottosistemi.
Definire un entry point per ogni sottosistema
-Flyweight:
Scopo: Separare la parte variabile di una classe dalla parte che può essere riutilizzata, in modo tale
da condividere quest’ultima tra differenti istanze.
Motivazione: uso della condivisione per supportare un grande numero di oggetti che hanno parti di
stato interno in comune e l’altra parte dello stato può cambiare
Applicabilità: un’applicazione usa un grande numero di oggetti. I costi di memorizzazione sono alti.
Gruppi di oggetti possono essere rimpiazzati da un numero minore di oggetti condivisi
-Proxy:
Scopo: Fornire un surrogato (o placehoder) per un altro oggetto per controllare l’accesso ad esso.
Motivazione: classe che funziona come interfaccia per qualcos’altro:
connessione di rete, un grosso oggetto in memoria, un file e altre risorse che sono costose o
impossibili da duplicare
Applicabilità:
Remote proxy
fornisce una rappresentazione locale per un oggetto in una
differenti spazio di indirizzi
Virtual Proxy
crea oggetti costosi su richiesta
Protection proxy
controlla l’accesso all’oggetto originale
Smart proxy
interpone azioni addizionali quando si fa accesso ad un oggetto:
conteggio del numero di referenze
caricamento dell’oggetto in memoria al primo riferimento
controllo che l’oggetto reale non sia accessibile