Sei sulla pagina 1di 20

Elementary Pattern, Anti Elementary Pattern e Pattern GRASP

Object Oriented
Rosario Turco

Introduzione
In questo lavoro introdurremo diversi concetti Object Oriented, che come vedremo costituiscono degli Elementary Pattern (EP), degli Anti Elementary Pattern (AEP), dei concetti GRASP . Gli EP, gli AEP e i GRASP sono utili per la verifica di correttezza di un progetto Object Oriented. In particolare GRASP sta per General Responsibility Assignment Software Patterns (or Principles) ed stato introdotto da Craig Larman. I GRASP sono dei Pattern generali di base, utili ad assegnare responsabilit alle classi. In generale se esistono i Pattern, come Best Practices da adottare, esistono anche degli anti-pattern da evitare. Lintento di un Pattern sempre quello trovare una soluzione (comprovata) ad un problema ricorrente, fornendo flessibilit ed evitando errori progettuali. Su EP, AEP e GRASP sono, poi, costruiti i Design Pattern (GoF, J2EE Pattern, etc.).

Verifiche progettuali Object Oriented


Per effettuare un buon Design e una rapida verifica progettuale Object Oriented importante introdurre i seguenti concetti elementari, alcuni dei quali si traducono poi in Best Practices, EP o AEP: Dominio delle classi Ingombro di una classe e la legge di Demeter Coesione di una classe Comportamento della sottoclasse Conformit di tipo o Principio di Liskov o principio della sostituzione Controvarianza e Covarianza Comportamento chiuso Partizionamento Le classi descrittive di unaltra Principio architetturale di Separation of concerns

Dominio delle classi Esistono sostanzialmente quattro domini, ognuno con la rispettiva classificazione delle classi.

Partendo dal basso, livello 0, verso lalto abbiamo: dominio fondazionale (livello 0) suddiviso in classi di tipo: o fondamentali, tipiche dei linguaggi, ad esempio come Integer, String, List, etc. o strutturali, come Pila, Stack, etc. tipicamente prodotte da noi o contenute anche nelle librerie dei linguaggi o semantiche, come Poligono, Punto, Temperatura, che hanno un significato pi ricco rispetto a Integer, String, etc. in sostanza per il valore che restituiscono lo stesso ad esempio un double. Queste classi non appartengono al dominio di business, sono ancora generiche. dominio architetturale (livello 1) suddiviso in classi di tipo: o comunicazione di rete (email, altri protocolli etc.) o comunicazione basi dati o interfaccia utente o infrastruttura di log dominio aziendale (livello 2) suddiviso in classi di tipo: o classi di attributo, cio classi del dominio di business come Saldo, TemperaturaCorporea (del paziente), diverse come significato da quelle fondazionali pi generali o classi di ruolo, come Cliente, Paziente (attori o ruoli) o classi di relazione, cio classi legate alle classi precedenti dominio applicativo(livello 3) suddiviso in classi di tipo: o daemon, che ascoltano eventi o processi gestori degli eventi

Il livello 0 del dominio fondazionale quello pi generale e riusabile, mentre salendo di livello diminuisce la riusabilit dei pezzi software nel caso si volessero riusare in altri progetti. Per le verifiche il concetto di dominio da accoppiare sempre con i concetti di ingombro e di coesione di una classe. 2

Ingombro delle classi Lingombro diretto di una classe linsieme dei soli riferimenti diretti che la classe ha rispetto ad altre classi. Lingombro indiretto di una classe linsieme di tutti riferimenti che partono dalla classe e che conducono a tutte le classi indirette. Aiuta molto la rappresentazione grafica UML durante lanalisi e la progettazione.

Nella Figura la classe A ha un ingombro diretto 3; mentre lingombro indiretto 5. Lingombro delle classi offre delle possibilit di verifica: La complessit di una classe maggiore quanto pi lingombro indiretto alto. Questo d una indicazione anche di quanto una classe lontana dalle classi di dominio fondazionale e quanto meno riusabile. Un ingombro inatteso ad un livello di dominio basso pu indicare un errore progettuale, tipicamente di coesione di una classe.

Elementary Pattern: Complessit e Riusabilit di una classe Problema: Come mantenere la complessit di una classe ragionevolmente bassa? Soluzione: Occorre mantenere basso lingombro indiretto della classe, se possibile. Strumento: Legge di Demeter

Per tenere basso lingombro di una classe la legge di Demeter suggerisce: Per un oggetto o appartenente ad una Classe C, con operazione op, ogni destinatario di un messaggio allinterno della operazione op deve essere: Loggetto stesso o Un oggetto a cui fa riferimento la segnatura di op Un oggetto a cui fa riferimento un attributo di o Un oggetto creato da op Un oggetto a cui fa riferimento una variabile globale 3

Ovviamente per le cose dipendono da cosa effettivamente dovremmo andare a modellare. Coesione di una classe La coesione di una classe una caratteristica fornitagli dallattinenza degli attributi e metodi rispetto allo scopo e responsabilit della classe. Un concetto facilmente intuibile ma difficilmente spiegabile con precisione assoluta. Un esempio se ho una classe Persona avr solo attributi e metodi attinenti ad una Persona e non ad un Aeroporto. Esistono i seguenti Anti Elementary Pattern di Coesione (AEP di coesione): Coesione di istanza mista Coesione di dominio misto Coesione a ruolo misto

Un esempio di Coesione a istanza mista, la possiamo immaginare se abbiamo una classe con un solo metodo ma gli oggetti hanno comportamento diverso. Ad esempio supponiamo di avere la classe AgenteDiCommercio e il metodo pagaProviggioni(). Inoltre mario e federica sono due istanze di AgenteDiCommercio. Per solo mario lavora effettivamente a proviggioni (es. 1000 euro questo mese) ma maria ha lo stipendio (1200 euro); per cui quando facciamo mario.pagaProviggioni() corretto che il risultato sia 1000 euro ma federica.proviggioni() da un risultato non definito, perch per federica non sono previste proviggioni. Lerrore che federica non pu essere istanza di AgenteDiCommercio direttamente. La soluzione derivare la classe AgenteDiCommercio come nella figura successiva spostando il metodo nella sottoclasse giusta e aggiungendo un metodo pagaStipendio(). Ovviamente federica deve essere istanza di AgenteDiCommercioConStipendio

Anti Elementary Pattern Coesione a istanza mista Problema: Come evitare di avere comportamenti anomali se la stessa classe viene usata da due istanze che in realt devono avere comportamento diverso (di una istanza si otterrebbe comportamento indefinito)? Soluzione: specializzare la classe, in modo che ognuno possa avere il comportamento appropriato.

Una classe ha un problema di Coesione a dominio misto quando essa ha un ingombro diretto con una classe estrinseca che appartiene ad un dominio diverso. Una classe B estrinseca rispetto ad A, se possiamo definire tutto di A senza aver bisogno di B. Una classe Elefante estrinseca alla classe Persona (tra laltro Persona non ha bisogno di farci riferimento) , mentre Data intrinseca perch pu cogliere laspetto di data di nascita della persona. Se stiamo progettando una classe Conto giusto avere un metodo che mi restituisca un oggetto di una classe Denaro o che abbia un attributo Data (la data del conto) ; mentre non sarebbe normale avere un metodo in Costo che mi restituisca un oggetto di dominio architetturale come CollegamentoTrasferimentoViaCavo. Occorre evitare di mettere insieme classi di domini diversi anche perch lingombro che si otterrebbe minerebbe ancor di pi la riusabilit. Ad esempio anche Real e Angolo non vanno mescolate insieme una fondamentale e laltra semantica, anche se per entrambe il valore un numero reale . Una classe con problema di Coesione a ruolo misto ha un ingombro diretto con una classe estrinseca dello stesso dominio. Qui come vedremo anche un problema GRASP di Expert. Persona e Cane sono ad esempio classi di ruolo del dominio aziendale. Non sarebbe normale che in Persona ci sia un metodo getNumeroDiCani(). Anti Elementary Pattern Coesione a dominio misto o a ruolo misto Problema: Come migliorare lestensibilit e la manutenzione del progetto, tra classi ingombrate direttamente? Soluzione: Evitare che lingombro diretto avvenga con classi estrinseche, di dominio diverso o dello stesso dominio Il progettista basandosi sui concetti di dominio, ingombro, estrinsicit, intrinsicit e coesione pu fare gi una serie di verifiche prima della implementazione del modello. Comportamento di una sottoclasse Lo stato di un oggetto il valore che in ogni momento assumono i suoi attributi. Sullo stato di un oggetto intervengono delle condizioni dettate dallinvariante, le precondizioni e le postcondizioni. Questi concetti fanno parte di una metodologia detta Design by Contract. Non sempre necessario considerare linvariante, ma almeno rifletterci sopra evita situazioni anomale e subdole. Linvariante di una classe una condizione che tutti gli oggetti della classe devono rispettare in un determinato stato. Esempio di Invariante Supponiamo la classe Triangolo con attributi a, b e c. Tutte le istanze di Triangolo devono sempre rispettare la condizione matematica (invariante) che: 5

INV1: a + b >= c and b + c >= a and a + c >= b Invece ad esempio se consideriamo la classe TriangoloIsoscele linvariante potrebbe essere: INV2: a = b or b=c or a=c Ancora che TriangoloRettangolo, se c lipotenusa ha invariante: INV3: a * a + b * b = c * c Ovviamente siamo in grado di evidenziare una gerarchia come nella figura successiva.

TiangoloRettangolo e TriangoloIsoscele ereditano da Triangolo linvariante INV1. Per cui TriangoloIsoscele deve soddisfare INV4 : INV1 and INV2 Mentre TriangoloRettangolo deve soddisfare INV5: INV1 and INV3 Infine TriangoloRettangoloIsoscele deve soddisfare: INV6 : INV1 and INV2 and INV3 Precondizioni e Postcondizioni Tutte le operazioni di una classe che agiscono sullo stato hanno precondizioni e postcondizioni. Tecnicamente invarianti, precondizioni e postcondizioni sono verificabili con le assert. Una precondizione la condizione che deve essere vera sullo stato prima che loperazione venga eseguita. Una postcondizione la condizione che deve essere vera sullo stato dopo che terminata lesecuzione delloperazione. 6

Esempio In uno stack vale la regola LIFO (Last in First out). E evidente che loperazione estraiItem() deve rispettare prima la precondizione che lo stack sia not empty (non deve essere nullo il numero di elementi in esso contenuti), altrimenti si va in errore. Se soddisfatta la precondizione loperazione, invece, mi pu restituire litem. La postcondizione di estraiItem() potrebbe essere di aggiornare il numero di item cio numItem = numItem -1 and not empty ovviamente uno stack provveder anche a eliminare dallo stack lelemento estratto. Conformit di tipo o Principio di Liskov o principio della sostituzione

Elementary Pattern Conformita di tipo Il principio di conformit di tipo dice che se S sottotipo di T allora S deve essere conforme a T. Il principio un EP ed detto anche Principio di Liskov. Detto in altri termini in tutti i contesti in cui c la superclasse possiamo sostituirla con la sottoclasse. Esempio Se un Cerchio sottoclasse di Ellisse, allora una qualsiasi operazione che in input si attende di ricevere come parametro Ellisse pu ricevere anche Cerchio. Precondizioni, postcondizioni, invarianti sono ereditate dalle sottoclassi. Elementary Pattern dellInvariante Linvariante di una sottoclasse restrittivo almeno quanto quello della superclasse o di pi . Labbiamo visto negli esempi dei triangoli di prima. Elementary Pattern delle Precondizioni Le precondizioni ereditate sono controvarianti, cio con segno opposto allinvariante. E intuitivo che devono per forza essere pi lasche o deboli di quelle delle superclassi. Elementary Pattern delle Postcondizioni Le postcondizioni ereditate sono covarianti, cio con segno nella stessa direzione dellinvariante, ovvero potrebbero essere pi restrittive. Esempi di controvarianza e covarianza come verifiche progettuali In figura abbiamo il diagramma UML di una superclasse e la sottoclasse, con le operazioni e gli attributi. Ricordiamo che invariante, precondizioni e postcondizioni sono condizioni che devono essere vere (tecnicamente attraverso le assert) che in particolare agiscono sulla verifica dello stato prima dellesecuzione di operazioni o alluscita da una operazione. La loro utilit che ci permettono di verificare se un sottotipo conforme al tipo.

Gli invarianti del sottotipo devono essere uguali o pi restrittivi, le precondizioni uguali o pi lasche (controvarianti), le post condizioni uguali o pi restrittive (covarianti).

Un Dirigente un Dipendente (lo so! State sbottando!). Il Dipendente ha un livelloQualifica > 0 mentre un Dirigente almeno livelloQualifica > 8. Quindi il Dirigente ha un Invariante pi restrittivo e il metodo che controlla ci isQualificaOk(). Ora valutazionePrestazioni immaginiamo sia un valore che varia tra 0 e 5, mentre il parametro percentualeGratifica varia tra 0% e 10%. Ma sicuramente i calcoli di gratifica sono diversi tra dipendente e dirigente; quindi in Dirigente c loverriding del metodo con stessa segnatura. Affinch Dirigente sia conforme a Dipendente per la precondizione di Dirigente per calcolaGratifica deve essere uguale o pi lasca di quella di Dipendente. Ma questo che vuol dire? Che nel calcolaGratifica il parametro di input deve avere un intervallo uguale o pi ampio (=lasco). Esempio da 0 a 5 sarebbe uguale, da 0 a 8 nel Dirigente sarebbe lasco. Non andrebbe bene, invece, da 0 a 3 (pi restrittivo). La postcondizione il controllo sullaltro parametro di output, che deve essere covariante. Ad esempio percentualeGratifica pu essere per Dirigente uguale o pi restrittivo es. 0% - 10% oppure 0% - 5%. Elementary Pattern - Principio del comportamento chiuso alle modifiche Rispettare linvariante anche il principio del comportamento chiuso alle modifiche. Il comportamento della sottoclasse deve essere chiuso alle modifiche.

In figura abbiamo che Triangolo eredita da Poligono il metodo. Se non c un controllo, aggiungendo un vertice al triangolo si otterrebbe un quadrilatero e non si rispetta linvariante, cio loggetto ottenuto non sarebbe un Triangolo. Per cui in questo caso si possono adottare varie soluzioni, a secondo delle esigenze: sovrascrivere il metodo con un altro in Triangolo in modo che non abbia effetto o che sollevi una eccezione) per evitare la violazione dellinvariante. Non usare aggiungiVertice() in Triangolo Essere pronti a ridefinire loggetto come Quadrilatero che eredita da Poligono, se ci accettabile

Partizionamento e Gerarchie di classi Quando una superclasse ha delle sottoclassi siamo difronte ad un partizionamento. Ad es.: Impiegato ha come sottoclassi Dipendente e Dirigente. Questo partizionamento {disjoint, complete}. I possibili valori che si possono accoppiare in una tripletta tra parentesi graffe sono: disjoint o overlapping, complete o incomplete, static o dynamic.

Elementary Pattern della classe Astratta o dellInterfaccia Solo quando siamo di fronte a {disjoint, complete} indipendentemente dal terzo, static o dynamic, allora la superclasse pu essere una classe astratta o una interface. Questo fatto importante perch se fosse {disjoint, incomplete} significa che il progetto pu subire estensioni in futuro per aggiunta di altre sottoclassi da gestire. Dynamic indica, ad esempio, che una sottoclasse nel tempo pu diventare unaltra sottoclasse .(es: da Dipendente a Dirigente). Errori classici di aggregazione, composizione, ereditariet Un errore banale confondere laggregazione con la composizione o con lereditariet. Nella composizione loggetto composto (totale) non pu esistere senza i suoi componenti. Generalmente i pezzi che costituiscono il tutto sono anche di genere diverso.

In figura un aliante non esiste se non ci sono tutte le sue parti. Quindi siamo di fronte ad una composizione (le ali sono due). 9

Nellaggregazione loggetto aggregato pu esistere senza le parti che aggrega. Laltra caratteristica che le parti aggregate sono dello stesso genere.

Una multinazionale un insieme di Societ, se ne viene a mancare la multinazionale continua ad esistere (almeno come una sola societ). Quando si parla di ereditariet pi corretto parlare di partizionamento di classi. Una volta con un neofita, parlando di gerarchia, tra superclasse e sottoclasse, nato lerrore come nella figura successiva. Ricordare che lereditariet esprime che il sottotipo un tipo della gerarchia superiore. Ma nella figura evidente che cos non .

Un Dirigente NON un AmministratoreDelegato e un Impiegato NON un Dirigente! Qualche progettino per vedere se abbiamo capito Cosa che non va nella figura che segue?

10

Apparentemente niente. In realt Panda giusto che un Orso. Quello che stona SpecieProtetta: allo stesso livello di dominio di Orso, essa pi generalizzata di Orso. E un problema di coesione a dominio misto. Ce ne accorgiamo anche se consideriamo delle istanze di Orso: Yoghi, Bubu; mentre le istanze di SpecieProtetta sono intere specie: topi muschiati etc. Inoltre lereditariet di Panda da Orso un partizionamento non completo, ci sono altri animali che possono essere considerati un Orso. Il che quando estenderemo la ereditariet multipla diventer difficile da gestire. Una piccola correzione dovrebbe essere fatta come nella figura successiva.

Ci rimane ora di legare le due parti in modo coerente come livello di dominio. Dobbiamo trovare la superclasse generica di Orso: un Orso ad esempio un Animale e una Specie un aggregato di Animali.

11

Vediamo un altro problemino che pu nascere estendendo nel tempo il progetto. Inizialmente abbiamo la figura successiva.

Una stanza un parallelepipedo. Poi ci si rende conto che le stanze possono essere anc he di diversa forma rispetto al parallelepipedo. Dobbiamo fare attenzione a quello appena detto: forma. Per cui adesso possiamo correggere il progetto.

Il prossimo esempio come evitare ancora problemi di coesione a dominio misto. Abbiamo un Cliente che fa Fatture che contengono Articoli. La Fattura inviabile tramite email, fax, etc.

12

Se modelliamo come in figura mischiamo la FatturaInviabile di dominio aziendale col dominio architetturale, perch dobbiamo esplicitare protocolli di inoltro della fattura. Una modifica semplice che migliora il tutto quella nella figura successiva.

La classe introdotta avr i metodi riguardanti il dominio architetturale. Questa classe introdotta spesso denominata classe mista perch supporta unastrazione utile in altre classi ma non appartiene ad esse come dominio. Solitamente sono classi astratte, che non si istanziano, ma hanno i metodi implementati. Elementary Pattern Classe Mista Problema: Come fare in modo che una classe di dominio aziendale non contenga attributi e metodi di un altro dominio ? 13

Soluzione: Aggiungere delle classi di supporto allastrazione della classe e spostare in essa attributi e metodi tipici dellaltro dominio In realt nei GRASP si ritrova anche come Pure Fabrication. Le classi descrittive di altre o classi nascoste nel dominio del problema Stiamo parlando di un problema tipico di classi non evidenti nel dominio del problema. Supponiamo che il cliente ci faccia capire che gli interessa i Voli e lAeroporto associato che gestisce. Una prima modellazione sarebbe come in figura.

Il problema di questa modellazione che se si cancellano i dati relativi a volo, non si hanno informazioni su quali voli sono disponibili verso laeroporto (la lista dei servizi insomma). Una soluzione di introdurre una classe descrizione della classe di cui si potrebbero non avere dati o cancellare i dati. Di seguito mostriamo la modellazione aggiustata.

Adesso anche se in un certo giorno non partono voli, se un cliente vuole sapere quali voli ci sono, questi sono descritti. Elementary Pattern Descrittore di Classe Problema: Allo sparire dei dati memorizzati da una classe si perdono informazioni sul servizio offerto. Soluzione: Introdurre delle classi descrizione della classe di cui si possono eliminare i dati

14

Separation of concerns Un Elementary Pattern Separation of concerns che un principio di pulizia architetturale quello di tenere separate le classi anche in base al loro ambito architetturale (package): presentation Logic domain logic database logic technical utility

Pattern GRASP Ora passiamo a vedere i GRASP, il cui compito quello di come assegnare le responsabilit alle classi.

GRASP Information Expert (Expert) Problema: Soluzione: Qual il principio generale di assegnare responsabilit ad una classe? Si assegna la responsabilit a quella classe che in grado di completare tutto il compito grazie ai suoi metodi (lesperto, colui che ha la conoscenza per completare il compito o il sotto compito)

Esempio Supponiamo di avere alcune classi che hanno bisogno di conoscere il totale di una vendita. Per il Pattern Expert dovremmo cercare tra le classi che hanno la conoscenza di come ricavare il totale.

In realt abbiamo applicato almeno tre volte lExpert. ProductDescription qua risolve il problema della classe nascosta ed lesperto del prezzo. VenditaLineItem lesperto che conosce le quantit dei prodotti e il sotto totale. Infine Vendita lesperto che pu ottenere il totale. Vantaggi: Si riduce laccoppiamento tra le classi (Low coupling), specie del la classe Vendita, difatti lingombro diretto minore e si aumenta la coesione (High Cohesion).

15

GRASP Creator Problema: Soluzione: Chi deve avere la responsabilit di creare una istanza di classe? Si assegna la responsabilit ad una classe B di creare una istanza di classe A se si verifica una o pi delle seguenti condizioni: B aggrega oggetti di A B contiene oggetti A B registra istanze di A B usa oggetti A B inizializza i dati da passare ad A per crearlo (B anche lesperto nellinizializzazione dei dati di A)

Esempio Nellesempio precedente Vendita contiene o aggrega VenditaLineItem. In questo caso Vendita pu essere il Creator di VenditaLineItem. Un sequence relativo che evidenzia il tutto nella figura successiva.

Qui abbiamo ipotizzato che Vendita abbia almeno un metodo makeLineItem(quantit) perch deve esserle detta la quantit con cui chiamare il metodo create(quantit) su VenditaLineItem. I Pattern correlati sono il Low Coupling, la Factory.

GRASP Low Coupling Problema: Soluzione: Come supportare un maggiore riuso e basso impatto al cambiamento? Si assegna la responsabilit in modo che si riduce laccoppiamento.

16

Esempio

Il Sequence mostra Registro che crea Pagamento e poi lo passa a Vendita in input con aggiungiPagamento. Registro lExpert e il Creator. Tuttavia per abbassare laccoppiamento/ingombro diretto possibile fare come nel sequence successivo dando la responsabilit di Pagamento a Vendita; cio il Creator di Pagamento Vendita.

GRASP High Cohesion Problema: Soluzione: Come mantenere la complessit gestibile? Si assegna la responsabilit in modo che la coesione si mantenga alta

Classi con bassa coesione sono classi che fanno troppe cose e non tutte attinenti tra loro. Ad esempio immaginate che Registro oltre a faiPagamento, abbia anche metodi come inoltraEmail(), avvisaSuperamentoSogliaTemperatura().

17

GRASP Controller Problema: Soluzione: Chi deve gestire un evento di sistema in input (dovuto ad un attore) ? Si assegna la responsabilit di ricevere input o gestire un evento di sistema in input ad una classe che rappresenti: Un intero sistema, un device o un sottosistema (Facade controller) Receiver o Handler Coordinator Session Controller

In sostanza c un attore che inoltra un input; mentre il Controller non una user -interface (gui) ma una classe di Ingresso che fa eseguire operazioni di sistema sullapplication server. E quindi un Facade che offre linterfaccia di ingresso al sistema e coordina il tutto.

GRASP Polimorfismo Problema: Come gestire alternative basate sul tipo? Come creare componenti software pluggable? Chi responsabile quando il comportamento varia per tipo? Quando alternative legate o comportamenti variano per tipo, assegnare la responsabilit di comportamento, tramite polimorfismo, ai tipi per i quali il comportamento cambia.

Soluzione:

Relazionato a molti Design Pattern: Adapter, Command, Proxy State, Strategy.

Esempio Supponiamo che dobbiamo disporre di diversi calcolatori di tasse forniti esternamente. In questo caso per assegnare la responsabilit di adattare il comportamento a diversi calcolatori usando il Polimorfismo una soluzione il progettino presentato in figura. DA notare che si tentato anche un partizionamento completo attraverso un Template <T>.

18

Le sottoclassi Adapter sono oggetti locali che poi attraverso API chiameranno i calcolatori esterni. Le implementazioni dei metodi sar differente e in input ognuno esamina loggetto Sale.

GRASP Pure Fabrication Problema: A chi assegnare la responsabilit se si in un caso in cui si viola Low Coupling e High Cohesion e le soluzioni offerte dallExpert non sono soddisfacenti? Assegnare la responsabilit ad una classe artificiale (fabrication) in modo che il progetto si mantenga pulito o puro (pure fabrication).

Soluzione:

Relazionato allElementary Pattern Classe Mista. Anche quellesempio un esempio di GRASP Pure Fabrication.

Altro esempio Supponiamo che Sale abbia bisogno di memorizzare su Database le informazioni; impensabile inserire i metodi di inserimento su DB su Sale. In questo caso si va ad ideare una classe PersistentStorage che collabora con Sale.

GRASP Indirection Problema: Come evitare un diretto accoppiamento tra due classi (per esigenza di configurazione o altro)? Come disaccoppiare in modo da avere basso accoppiamento e riuso pi alto e proteggersi dalle variazioni? Assegnare la responsabilit ad un oggetto intermedio che va a mediare tra gli oggetti che prima erano direttamente ingombrati

Soluzione:

Relazionato ai GRASP Protected Variations, Low Coupling e Pure Fabrication, ai GoF Adapter, Bridge, Faade, Observer e Mediator Lesempio precedente dei calcolatori anche un esempio di GRASP Indirection oltre che di Polimorfismo. Le sottoclassi oltre ad adattare il comportamento sono anche degli oggetti intermedi che vanno a mediare chiamando le API dei veri calcolatori esterni. Lesempio di Sale nel GRASP Pure Fabrication anche un esempio di GRASP Indirection. Abbiamo disaccoppiato Sale dal Database introducendo una classe artificiale o mista che fa da mediator.

19

GRASP Procted Variations Problema: Come disegnare oggetti, sottosistemi, sistemi in modo che una variazione su uno di essi non abbia grosso impatto sugli altri? Come proteggersi dalle variazioni? Individuare i possibili punti di variazione futura o di instabilit attuale e assegnare la responsabilit in modo da incapsulare la variazione con stabili interfacce intorno a tali punti.

Soluzione:

Tutti gli strumenti dellObject Oriented sono nati per evitare una serie di problemi: data incapsulation, interface, polimorfismo, indirection, standard, pattern. Questo principio il principio su cui sono nati i Design Pattern; per cui ad esso sono relazionati tutti i Design Pattern GoF [DR6]. Riferimenti
[DR1] Rosario Turco Concetti di base Object Oriented [DR2] Rosario Turco Principi di Disegno [DR3] Rosario Turco Usabilit e ripetibilit dei processi produttivi software [DR4] Rosario Turco Modellare con lUML ed i colori [DR5] Rosario Turco Design Pattern Pattern e-book: una guida nella jungla dellOO [DR6] Gamma, Helm, Johnson,Vlissides Design Patterns Elementi per il riuso di software a oggetti Prima edizione italiana [DR7] Rosario Turco Risoluzione di problemi con UML [DR8] Rosario Turco Tradurre le relazioni UML in C++ [DR9] Rosario Turco - Refactoring: la teoria in pratica [DR10] Rosario Turco Disegno per il riuso e con il riuso [DR11] Rosario Turco Framework e UML [DR12] Rosario Turco Il Business AS IS Modeling con UML [DR13] Rosario Turco Extreme Programming [DR14] Rosario Turco Rational Unified Process [DR15] Rosario Turco BPM, SOA e Business Rules Engine, lultima frontiera [DR16] Rosario Turco Progettazione a componenti [DR17] Rosario Turco - Metodologia Agile

20