Composite



Scaricare 0.68 Mb.
Pagina5/7
03.04.2019
Dimensione del file0.68 Mb.
1   2   3   4   5   6   7

4. Chain of Responsability

Supponiamo di avere un sender ed un insieme di receiver.

Il sender invia una richiesta ad uno dei receiver il quale:

- se è in grado di gestire la richiesta, la gestisce;

- se non ne è in grado delega la richiesta ad un altro receiver.
In questo modo il sender non conosce quale receiver gestisce la sua richiesta, ma semplicemente invia una richiesta al primo receiver della catena (chain) e la richiesta viene inoltrata finché non viene soddisfatta da qualcuno. Cioè sender e receivers non sono collegati strettamente tra loro, così come la metodologia object-oriented insegna.
Esempio:

Consideriamo un’applicazione dotata di un help contestuale.



Figura 29 - diag29.wmf


L’utente può ottenere informazioni su ogni parte dell’interfaccia semplicemente cliccando su di essa. L’help fornito dipende dalla parte di interfaccia selezionata e dal suo contesto. Per esempio il bottone Stampa di una dialog box (finestra di dialogo) potrebbe far riferimento ad informazioni di help differenti da quelle riguardanti il bottone Stampa della finestra principale. Se non esistono informazioni specifiche per una data parte dell’interfaccia, l’help system visualizza un messaggio di help riguardante l’immediato contesto ( la dialog box nel suo insieme, per esempio ).
Schematicamente si ha:

Figura 30 - diag30.wmf


Gli oggetti (Button, Dialog box, Application,  ) sono organizzati in modo gerarchico e sono in relazione fra loro secondo la relazione part of ( P.O. ). Ogni anello della chain ha zero o 1 successore. I predecessori possono essere più di uno.


Figura 31 - diag31.wmf


Nel caso considerato, anche l’help handling (H.H. o gestione dell’help) ha una struttura gerarchica, per cui le due strutture coincidono, ma in generale la catena di deleghe che si forma è totalmente indipendente dalla struttura dell’applicazione.

Figura 32 - diag32.wmf


Quindi per gestire la Chain of Responsability dobbiamo considerare solo i tratti che la riguardano, cioè quelli tratteggiati.
Tornando all’esempio, siamo in un caso di eredità multipla:

Figura 34 - diag34.gif


Successor si basa sul concetto di delegation. Attraverso esso ogni classe è in grado di conoscere qual è il suo successore nella Chain of Responsability.
Poiché, come abbiamo già detto, in questo esempio la struttura gerarchica dell’applicazione (che interessa Widget, PushButton, ScrollingBar, MenuBar) coincide con la Chain of Responsability (HelpHandling), possiamo risolvere elegantemente come segue, introducendo il concetto di mixin class.

Figura 35 - diag35.gif


La mixin class (HelpHandler) è una classe dalla quale vengono fatte derivare le classi già esistenti. Essa viene usata nei casi particolari di eredità multipla, in cui esiste già una gerarchia (o un’altra struttura) e la Chain of Responsability è una gerarchia (o un’altra struttura) che si sovrappone a quella già esistente.
La mixin class gestisce l’help, quindi può essere parent anche di altre classi già esistenti che non hanno a che fare con la Chain of Responsability considerata (nell’esempio Application e Socket).
A livello di implementazione occorrerà tener conto del fatto che:


  • la classe HelpHandler può essere astratta o concreta, a seconda che la sua operazione Help() venga implementata nella classe stessa oppure specializzata solo a livello delle sottoclassi;




  • nel caso in cui la classe HelpHandler venga implementata e poi specializzata laddove sia necessario, la richiesta riceve comunque una risposta di default;




  • qualora abbia senso che l’ultimo anello della catena, non sapendo rispondere, lasci cadere la richiesta ( non è il caso dell’Help, ma potrebbe interessare il caso della Ricerca ) è sufficiente non prevedere risposte di default e usare una classe HelpHandler astratta.



Figura 36 - diag36.wmf


Il pattern generico (che si basa sui concetti di delega, attraverso Successor, ed ereditarietà multipla) per realizzare la Chain of Responsability è il seguente:

Figura 37 - diag37.gif


Esercizio:
La gestione delle raccomandate da parte delle PPTT prevede la seguente procedura:


  • L’utente presenta la missiva a uno sportello. Essa viene identificata unicamente da un codice a barre che indica:

- ufficio di provenienza

- destinazione

- anno, mese, giorno, ora, minuto, secondo di codifica.

In tal modo i codici sono non ambigui per qualsiasi raccomandata. L’utente riceve copia del

codice (ricevuta).


  • Nello smistamento del traffico la missiva passa da un ufficio PPTT ad un altro. Nei Data-Base di ogni ufficio viene registrato l’ingresso della missiva (anno, mese, giorno, ora, minuto, secondo) e l’uscita con annotazione della destinazione.




  • Se un utente lamenta lo smarrimento di una raccomandata, egli può recarsi presso qualsiasi sportello delle PPTT per conoscere la «storia» della sua raccomandata.

Definire l’architettura del sistema automatico di tracing tenendo conto del seguente scenario:




  • Gli uffici periferici accorpano le missive in pacchi per gli uffici centrali. Tali pacchi sono elaborati su base C.A.P. e spacchettati a destinazione.




  • E’ previsto un ufficio periferico in ogni località (comune - frazione), un ufficio zonale in ogni provincia, un ufficio regionale in ogni capoluogo di regione, un ufficio centrale in ogni distretto (sono 5 in tutta Italia).

NB: Le interrogazioni al sistema restituiscono tutta la storia della missiva.


Soluzione:
Gli uffici postali che si scambiano le missive sono organizzati secondo una struttura gerarchica le cui foglie sono gli uffici periferici di ogni località ed ai livelli superiori ci sono gli uffici zonali, quelli regionali ed infine i 5 uffici centrali.

I nodi di questa struttura gerarchica sono collegati da archi di raccolta ed archi di distribuzione di missive.



Figura 38 - diag38.wmf


Il passaggio della raccomandata nei vari uffici viene registrato nei Data-Base, per cui è possibile risalire al percorso effettuato dalla missiva.

Figura 39 - diag39.wmf

Supponiamo che l’utente si rechi all’ufficio di Bra per chiedere la storia della raccomandata partita da Brignole per Rialto.

L’utente consegna la propria ricevuta con il codice a barre (CB) che dice che la raccomandata è partita da Brignole.

La query informativa sui Data-Base si propaga da Bra a Brignole e da Brignole viene seguito il tracing lasciato dalla raccomandata sui vari Data-Base degli uffici che ha attraversato.

Fitura 40 - diag40.wmf


Notiamo che ci sono due catene:


  • quella che va dall’ufficio in cui l’utente lamenta lo smarrimento di una raccomandata (Bra), all’ufficio dal quale è partita la raccomandata (Brignole);




  • quella che va dall’ufficio dal quale è partita la raccomandata (Brignole), ai vari uffici che dicono dove è realmente passata la raccomandata.

A questo punto ci sono due possibilità:

- la raccomandata è giunta a destinazione;

- la raccomandata è stata smarrita durante il tragitto.


Una possibile soluzione è la seguente:

Figura 41 - diag41.gif


Supponiamo che la raccomandata sia giunta fino a Venezia città e poi sia stata smarrita.

Il codice a barre CB contiene «Brignole», cioè l’ufficio da cui la raccomandata è stata spedita.

Tramite Query(CB) si risale la catena da Bra a Brignole. Gli anelli intermedi riconoscono di non essere Brignole leggendo il codice a barre passato come parametro e rifanno la Query(CB) all’anello successivo (noto grazie a Successor, che in questa chain si chiama Querying).
Brignole si riconosce come sorgente, allora cambia la Query(CB) in Trace(CB , Brignole) e man mano che si risale la catena Genova-Città, Liguria, eccetera rifanno la Trace() lasciando traccia in una lista (la classe Path) fra i parametri della Trace(). Per esempio Genova-Città invia la

Trace(CB , Brignole,Genova-Città) al suo Successor e così via.

In questa chain il Successor è chiamato Tracing.
Rialto che non ha mai visto la raccomandata restituisce Fail .

La trace con Fail a Rialto viene restituita a Bra.


NB: Query() e Trace() restituiscono un tipo Path.
Notiamo infine che Raccolta e Distribuzione sono catene statiche usate per semplicità (altrimenti sarebbe stato necessario introdurre delle sottoclassi di UfficioPT).

Query e Trace sono catene dinamiche.






Condividi con i tuoi amici:
1   2   3   4   5   6   7


©astratto.info 2017
invia messaggio

    Pagina principale