Pattern Comportamentali PDF

Title Pattern Comportamentali
Author NeoX v Andrew
Course Ingegneria del software
Institution Università degli Studi di Catania
Pages 23
File Size 2 MB
File Type PDF
Total Downloads 83
Total Views 177

Summary

Pattern Comportamentali...


Description

Pattern Comportamentali

Template Method L’obiettivo di questo pattern è definire la struttura di un algoritmo in un metodo lasciandone alcune parti non specificate. L’implementazione delle parti non specificate è in altri metodi la cui implementazione è delegata alle sottoclassi. Le sottoclassi ridefiniscono solo alcuni passi dell’algoritmo, non la struttura generale.

La Classe Concreta è una sequenza di operazioni primitive. Dunque, l’abstract Class contiene il templateMethod che consente di effettuare una serie di operazioni, ma poi ci sono delle operazioni primitive

che possono essere implementate all’interno di una classe concreta al fine di implementare i metodi che non sono stati implementati all’interno della classe Padre (Abstract Class).

Strategy L’obiettivo è definire una famiglia di algoritmi, incapsularli e renderli intercambiabili. Dobbiamo permettere agli algoritmi di variare. Mentre Template Method usa l’ereditarietà, Strategy usa la composizione.

Il metodo alg contiene tutti i passi dell’algoritmo complesso. Il metodo op della classe c consente di invocare il metodo alg della classe S1. Ho complicato lo schema. Intanto alcuni vincoli che non vorrei avere: da alg potrei aver bisogno di accedere ad attributi di C dunque mi serve anche una navigabilità da S1 a C. Inoltre, la classe C potrebbe essere configurata per usare S1, dunque, potrei avere una classe S1 ma anche una classe S2. Quindi potrei avere S1 che implementa alg e S2 che implementa alg, lo stesso algoritmo ma implementato in maniera diversa cambiando il parametro che passo al costruttore di C.

Si parla di strategy per il fatto che organizzando gli algoritmi così posso far decidere al cliente quale tipo di algoritmo usare in un particolare caso. Ovviamente stiamo parlando di algoritmi che fanno la stessa cosa ma possono avere caratteristiche diverse in termini di memoria che occupano, ecc.

State Lo scopo è permettere a un oggetto di cambiare il suo comportamento al variare del suo stato interno. Per fare ciò si estrae la rappresentazione dello stato in classi esterne, organizzate in una gerarchia di classi (che rappresentano i diversi stati) e si sfrutta il polimorfismo per variare il comportamento.

Consideriamo questo diagramma di macchina a stati.

In questo caso il click del pulsante è fortemente dipendente dallo stato della porta.

E’ da evitare una situazione in cui uso una serie di switch, if. Con questa serie di if andare a controllare se essi rispecchiano il diagramma è complesso, ma nel momento in cui voglio cambiare il comportamento click devo andare a modificare il codice che si trova annegato in tante altre cose, ho un comportamento cablato all’interno di un metodo e non va bene. Facciamo una gerarchia di classi in cui ogni sottoclasse rappresenta un possibile stato ciascuno dei quali implementerà in maniera differente il metodo click() che come sappiamo dipende dallo stato e dunque lo metto nelle sottoclassi.

Questo è il diagramma che viene fuori applicando il pattern State.

In tal caso ho uno stato che è una classe astratta e poi ho una serie di classi concrete ciascuna delle quali rappresenta un possibile stato. Il metodo richiesta() dipende dallo stato in cui mi trovo. Con il pattern state ho una distribuzione del comportamento nelle varie sottoclassi, e questo è buono ma vi sono dei contro: ho un’applicazione meno compatta in quanto aggiungo altre classi, inoltre, ogni sottoclasse deve conoscere altre sottoclassi. Dunque, questo pattern va applicato tutte le volte in cui abbiamo molti stati con molte scelte condizionali. Questo pattern mi consente di effettuare un mapping diretto con il diagramma di macchina a stati.

Command L’idea è di incapsulare una richiesta in un oggetto consentendo di parametrizzare i client con richieste diverse, di mantenere uno storico delle richieste. Se una richiesta, un comando è un oggetto, esso può avere vita propria.

Il Receiver è chi riceve il comando vero e proprio, il Client si occupa dell’istanziazione di un comando.

Il Client crea un nuovo comando e tramite setCommand( c) lo passa al receiver, il quale esegue il comando che produce un’azione che viene passata al Receiver.

Observer È importante in quanto è ampiamente applicato. L’obiettivo è avere oggetti che osservano lo stato di un oggetto e sono notificati e aggiornati immediatamente quando lo stato cambia. In pratica vogliamo utilizzare un oggetto che osserva lo stato di un oggetto in modo che se lo stato cambia mi viene immediatamente notificato.

Ho un oggetto che ha uno stato che può cambiare. Come realizziamo il fatto che un oggetto possa osservare lo stato di un altro oggetto? Usiamo attributi pubblici? No! Gli osservatori invocano continuamente un metodo cambiato dell’oggetto osservato? Problemi! L’osservatore potrebbe:

 “rompere” troppo all’osservato  scoprire la variazione troppo tardi  “perdersi” la prima di due variazioni “veloci”  E se ho tanti osservatori? Poco scalabile! L’osservato passa il tempo a rispondere (magari senza nessuna variazione) In tal caso piuttosto che essere l’oggetto osservatore ad andare a controllare sempre lo stato, facciamo si che sia l’oggetto che cambia il suo stato a comunicare all’osservatore che ha cambiato stato, non il viceversa. Ovviamente per notificare ciò agli osservatori, occorre invocare dei metodi.

L’oggetto osservato non ha necessità di conoscere l’identità precisa degli osservatori, la cosa importante è che nel momento in cui cambia lo stato, questo possa essere comunicato agli osservatori. Inoltre, vorrei che gli osservatori possano essere aggiunti o rimossi a run-time.

Abbiamo gli Osserver e l’oggetto osservato (Subject). Per rendere il tutto più generale possibile ho Subject e Observer che sono classi astratte ma poi ho anche le classi concrete. Notify va a chiamare il metodo update() su tutti gli Observer. Quando viene invocato il metodo update() su un ConcreteObserver questo acquisisce lo stato dell’oggetto osservato.

Ho una fase preliminare in cui i diversi Osservatori si registrano presso l’oggetto concreto osservato.

Se un osservatore osserva più oggetti, come fa a sapere chi ha variato lo stato? Magari l’oggetto che ha variato lo stato può essere un parametro passato al metodo update. Modalità pull: modalità in cui update() non passa alcuna informazione sullo stato ma sarà l’osservatore che userà getState() per ricavare lo stato. Modalità push: update() passa anche lo stato.

Il pattern observer è noto come MVC (Model View Controller), in cui l’oggetto osservato e l’observer sono rispettivamente il Modello e la View. Questo pattern viene utilizzato in contesti grafici, ma anche in altri contesti, ad esempio ambito distribuito.

Mediator

L’obiettivo è incapsulare in una classe le modalità di interazione fra oggetti evitando a tutti gli oggetti di conoscere tutti gli altri. In pratica vi è un oggetto mediator che media l’interazione fra tutti gli oggetti.

Qui abbiamo tre classi A, B, C che comunicano tutte tra loro.

Introduco una classe M che contiene i metodi aM, bM, cM(), in cui in aM vado a mettere tutti i metodi di a che consentono di interagire con gli altri oggetti, stessa cosa per bM e cM. In tal modo sto riducendo l’accoppiamento tra A, B, C. Per specializzare una modalità di comunicazione basta aggiungere una sottoclasse M e basta, e in tal caso basta sostituire A con A1 e A2.

Le classi ConcretePartner1 e ConcretePartner2 conoscono il ConcreteMediator. Memento lo saltiamo

Iterator L’idea è di fornire un modo di accesso sequenziale agli elementi di un oggetto composto senza esporre la struttura dell’oggetto composto, ad esempio io voglio scorrere la lista senza obbligare a chi lo fa di conoscere la struttura della lista.

L’oggetto Composto crea un iteratore mentre l’Iteratore restituisce il prossimo elemento, e tenendo traccia dell’ultimo elemento visitato dice se è possibile ancora scorrere la lista.

Saltare Visitor

Chain of Responsibility Esso evita l’accoppiamento fra mittente di una richiesta e destinatario. In tal caso più oggetti possono soddisfare la richiesta, gli oggetti sono concatenati, essi si passano la richiesta lungo la catena, finché un oggetto riesce a soddisfarla.

Se la richiesta arriva a fine catena, non è gestita, inoltre, è possibile cambiare dinamicamente la “catena”, cambiando l’ordine, aggiungendo o eliminando elementi. La richiesta viene rappresentata mediante l’invocazione di un metodo (eventualmente statico) oppure mediante il passaggio di un parametro con codice richiesta.

Interprete L’idea è che dato un linguaggio, occorre definire una rappresentazione per la sua grammatica, e un interprete che usa la rappresentazione per interpretare le frasi del linguaggio. Dell’interprete (interprete) occorre sapere soltanto questo, nient’altro....


Similar Free PDFs