Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
INDIRECTION
Il pattern fornisce una soluzione al problema:
Come assegnare una responsabilità per evitare l’accoppiamento diretto tra due elementi? Come disaccoppiare e
mantenere alta la riusabilità?
La soluzione consiste nell’assegnare la responsabilità a un oggetto intermediario che crea una indirezione tra i
componenti.
Esempio di Indirection
IAccountingAdapter, PersistentStorage, Cup sono tutti esempi che supportano Indirection
Banalmente, se succede un cambio di requisiti la modifica non si ripercuote a catena se le classi non sono molto
accoppiate.
È molto simile alla pure fabrication ma con alcune piccole differenze sottili.
Nel caso dello studio del pos supponiamo che a un certo punto dobbiamo andare a dialogare con il sistema di
contabilità della banca. Per questo potremmo avere bisogno di fare ricorso al modem del nostro calcolatore per
poter andare su internet.
In figura compare la classe CreditAuthorizationService che senza una classe Modem dovrebbe comunicare
direttamente con l’oggetto hardware, andandone ad invocare le API.
Se tale programma, senza la classe Modem, venisse utilizzato per modem diversi, dovremmo modificare la classe
CreditAuthorizationService stessa, cosa che non vogliamo.
Con la presenza della classe Modem i possibili cambiamenti non si ripercuotono sulle classi del dominio
ed è una classe ottenuta dall’applicazione del pattern
applicativo. È una sorta di driver indirection.
PersinstentStorage è un oggetto di indirezione: se cambia la basi di dati non devono essere cambiate le classi
dello strato applicativo ma solo la classe PersistentStorage.
Un altro esempio è AccountAdapter e allo stesso modo Cup.
61
Matilde Simonini Ingegneria Informatica anno 2022/2023
Pro e Contro di Indirection
Vantaggi Controindicazioni
Supporta l’accoppiamento basso Se usato eccessivamente, si ottiene una
Migliora la riusabilità moltitudine di classi con un solo metodo
PROTECTED VARIATIONS
Si tratta di un principio generale dello sviluppo sw che misura anche la maturità del programmatore.
Il pattern va usato con discernimento.
Il pattern fornisce una soluzione al problema:
Come progettare uno o più oggetti in modo tale che l’instabilità di questi oggetti non abbia un impatto indesiderato
su altri oggetti?
consiste nell’identificare i
La soluzione punti in cui è prevedibile instabilità e assegna delle responsabilità per
creare una interfaccia stabile attorno ad essi.
Esempio metodo dell’altra
Due classi potrebbero essere accoppiate perché una fa ricorso anche solo e questo può dar vita
alla controindicazione presentata.
Un esempio di punto di stabilità nel sistema pos è il punto di interfacciamento con il sistema di contabilità.
⇒
Il punto di instabilità sono le classi intermedie sotto se cambiano le API del sistema di contabilità cambierà il
codice degli adattatori e non tutto il resto. Le classi del dominio applicativo sfruttano solo tali interfacce.
Pro e contro di Protected Variation
Vantaggi Controindicazioni
Estensioni richieste facili da aggiungere Il costo per la realizzazione della protezione
Accoppiamento più basso nei punti di cambiamento può essere più
Ridotto impatto dei cambiamenti elevato di quello della realizzazione di un
progetto semplice
Ci sono due tipi di punti di cambiamento:
Punto di variazione: una variazione del sistema nei requisiti correnti
Punto di evoluzione: una variazione che potrebbe sorgere in futuro (non è nei requisiti correnti)
Nel caso dei punti di evoluzione il pattern appena visto dovrebbe essere applicato pensandoci bene.
Gli sviluppatori inesperti creano, generalmente, progetti molto rigidi che comportano il cambiamento di tante
porzioni di codice. I programmatori intermedi creano soluzioni troppo flessibili, mentre i più esperti utilizzano il
pattern appena visto solo quando strettamente necessario.
Legge di Demetra
È una specializzazione di Protected Variation per cui ogni classe parla solo con le classi con cui ha diretta
dipendenza.
Impone di evitare di inviare messaggi a oggetti indiretti.
Elimina la fragilità rispetto ai cambiamenti nella struttura del progetto (punto di instabilità comune)
62
Matilde Simonini Ingegneria Informatica anno 2022/2023
Con chi si può parlare?
L’oggetto Un oggetto creato all’interno del metodo
this
Un parametro del metodo Un elemento di una collezione che è attributo
Un attributo di this di this
Esempio di cosa non fare
Per essere più rispettosi della legge di Demetra possiamo aggiungere metodi ai famigliari.
Nel primo esempio potrebbe essere aggiunto un metodo alla classe Sale.
Un esempio di OOA e OOD
Abbiamo visto, nei paragrafi passati, come sfruttare gli strumenti UML in una catena di montaggio del software.
Non abbiamo visto nei dettagli in che modo usarli. Ora che abbiamo visto in principi grasp possiamo rivedere la
catena di montaggio software a partire dai casi d’uso.
Si parte dalla relazione dei casi d’uso.
Nel caso del pos, ad esempio, lo scenario principale potrebbe essere quello in cui il cliente arriva e si inizia con
una nuova vendita.
Il caso d’uso suggerisce le operazioni di sistema mostrate negli SSD (makeNewSale, enterItem, endSale,
makeCashPayment).
Le operazioni di sistema negli SSD sono i messaggi entranti nei Controller dello strato di dominio!
Quindi per gli eventi di sistema è possibile fare il diagramma di sequenza di sistema, oppure più semplicemente
possono essere identificati nei casi d’uso.
progettazione del caso d’uso di avviamento per ultima.
Si consideri la Operazione makeNewSale
Per ciascuna delle operazioni di sistema va effettuata una progettazione, per la quale ci si può avvalere dei
contratti (in essi si deve far riferimento agli oggetti concettuali trovati in fase di analisi).
63
Matilde Simonini Ingegneria Informatica anno 2022/2023
Controller per operazione makeNewSale
A questo punto per il particolare evento di sistema bisogna procedere con la fase di progettazione.
scelta di progetto consiste nell’identificare il Controller!
La prima
La prima decisione da prendere riguarda l’attribuzione delle responsabilità ad un controller, per la quale si sfrutta il
pattern grasp Controller.
In questo caso ci accontentiamo di un unico controllore.
In base al pattern Controller, possibili scelte sono POSSystem, Store, Register, ProcessSaleHandler.
linea guida, mentre l’ultimo suggerimento deriva dalla seconda linea
I primi tre suggerimenti derivano dalla prima
guida del pattern controller.
Fra le varie proposte viene scelta Regster.
Realizzazione operazione makeNewSale
Chi è il responsabile di creare una Sale?
E di creare una lista vuota di SalesLineItem?
Il contratto è una sorta d passo intermedio per arrivare alla progettazione. Si può anche evitare tale passaggio e
utilizzare solo i casi d’uso per la progettazione.
E infine l’avviamento
progettazione dell’inizializzazione
La va fatta per ultima.
È necessario creare un oggetto di dominio iniziale o un insieme di oggetti di dominio iniziali di pari grado nel main
oppure da una Factory invocata dal main.
Bisogna scegliere come oggetto di dominio iniziale una classe (vicino) alla radice della gerarchia di contenimento
degli oggetti di dominio:
Un facade controller (es. Register)
Un oggetto che può contenere tutti (o quasi) gli oggetti (es. Store)
Poiché si tratta di una responsabilità che riguarda la creazione dovrà essere utilizzato il pattern grasp Creator.
Nel modello di dominio del pos compaiono lo Store e Register ai quali può essere attribuita la responsabilità in
questione.
La vendita corrente può essere concepita come tentativo di vendita e viene attribuita a Register, che corrisponde al
controller e che si prende direttamente in carico la gestione dell’evento di sistema makeNewSale, cosa che va
bene per un numero limitato di eventi di sistema.
che il controllore tenga conto dello stato del caso d’uso, che comprende lo stato della vendita corrente.
È giusto 64
Matilde Simonini Ingegneria Informatica anno 2022/2023
Tra gli attributi di s ci sono anche le salesLineItem, ragione per cui dobbiamo occuparci di inizializzare tale lista,
che inizialmente sarà vuota. Il responsabile della creazione, per Creator, deve essere il contenitore che inizializza i
propri contenuti e quindi si attribuisce la responsabilità a Sale.
Esempio di avviamento
L’avviamento dovrebbe essere pensato come ultima cosa in quanto avendo a disposizione di tutti gli elementi
dell’applicazione, siamo anche in grado di determinare come questi devono essere inizializzati.
Per l’avviamento è necessario creare degli oggetti di dominio iniziale, ossia gli oggetti radice che contengono
sostanzialmente tutti gli altri.
viene creato l’oggetto di dominio iniziale (Store)
Nel main e anche i suoi figli.
Una volta creato l’oggetto radice, il caso d’uso di avviamento ha anche il compito di associare il MVC controller al
grasp controller.
I due controllori ci saranno sempre: il primo per il lato di presentazione e il secondo per il lato dominio.
Il controller MVC è ProcessSaleJFrame mentre Register è il controller grasp.
per la realizzazione dell’avviamento
Diagramma di interazione
Compare quello che potrebbe essere il risultato dell’analisi dei vari casi d’uso.
Dagli eventi di sistema nascono alcune esigenze.
Compare l’attribuzione delle responsabilità derivate dalle necessità emerse dall’analisi dei vari eventi di sistema.
dell’implementazione del caso d’uso di avviamento.
Si tratta 65
Matilde Simonini Ingegneria Informatica anno 2022/2023
Principi solid e altri
I principi SOLID di Robert Martin
Sono un acronimo dove ogni lettera sta per uno dei 5 principi.
Single responsibility: ogni classe dovrebbe avere una sola responsabilità (alta coesione)
una classe dovrebbe essere aperta all’estensione, ma chiusa alle modifiche.
Open-closed:
In altri termini una classe dovrebbe essere estesa senza che il codice venga modificato.
Liskov substitution: ogni superclasse dovrebbe essere rimpiazzabile da una sua sottoclasse, senza
modificare il significato del programma
meglio tante interfacce, una per ciascun cliente, che un’unica interfaccia buona per tutti
Interface segregation:
Dependency inversion: meglio dipendere dalle astrazioni che dalle implementazioni
Dobbiamo capire cosa si intende con il concetto di responsabilità e dobbiamo entrare in confidenza con il concetto