You are on page 1of 27

Progettazione a componenti

ing. R. Turco (rosario_turco@virgilio.it)

Vantaggi di una progettazione a componenti


La progettazione a componenti, collocata in una corretta metodologia (Catalysis,
Design Pattern, J2EE, COTS, etc) favorisce molteplici vantaggi progettuali:
 La riusabilità nei progetti
 L’acquistabilità di componenti di alto livello (COTS)
 La flessibilità al cambiamento dei requisiti
 La creazione di architetture SOA
 La sostituibilità (incapsulamento) con un altro componente
 L’aggiornamento di un componente con nuove funzionalità
 La realizzazione di prodotti basati su Java, che fanno uso di componenti di alto
livello (palette ad esempio di BusinessWorks TIBCO)

Componenti che devono rispettare molte esigenze, come sopra, tendono ad avere una
astrazione molto alta ed essere general purpose (COTS); se si riducono, invece, le
esigenze da rispettare, allora il componente è maggiormente calato sul business che
deve realizzare in ambito architetturale.

La progettazione a componenti si basa su tutti i principi dell’OO vista in


[DR2][DR3][DR4][DR5][DR8] e dei Design Pattern vista in [DR9]. Esiste una
sfumatura e/o una somiglianza tra i componenti ed i framework [DR13] ma, in questo
caso, la cosa dipende molto da cosa si intende per componente, come vedremo in
seguito; in certi casi le due cose coincidono.

La progettazione dei componenti è indipendente dalla tecnologia.

I tre principi elementari su cui poggiano i componenti sono:


 Specifiche di interfaccia: Un componente è un macro-oggetto con una specifica
di interfaccia (pubblica) e una specifica di comportamento (privata), che agisce
su classi, metodi e dati, ed è nascosta l’implementazione, gli oggetti/classi, le
1
librerie, i file, la dislocazione di ogni partecipante al componente etc. In
sostanza di un componete è nota la specifica di interfaccia o contratto d’uso e
cosa farà o restituirà.
 Incapsulamento: Il client che chiama il componente dipende solo dalla specifica
di interfaccia di quest’ultimo e non deve interessarsi (né lo sa) come avviene il
funzionamento interno al componente (memorizzazione dati in strutture dati,
metodi privati etc)
 Identità: Il componente ha una identità unica indipendentemente dallo stato
interno.

I tre principi di sopra consentono di:


 lavorare in termini Object Oriented
 rendere indipendenti i client dal componente fisico
 favorire la sostituibilità o l’aggiornamento di un componente a parità di
interfaccia con minimo impatto dei client

Cosa si intende per componente?


Da un punto di vista teorico-progettuale (disegno) è semplice parlare di un
componente logico: è un insieme di classi correlate e cooperanti che forniscono un
servizio finito; ma se si vuole comprendere cosa è un componente fisico va
innanzitutto calato il discorso nella tecnologia da usare e nello standard in essa
definito per componenti.

In Java e in ambito J2EE, i componenti fisici sono degli EJB (Enterprise Java Beans)
che possono essere sottoposti a deploying tramite un impacchettamento fisico
denominato EAR. Sull’EAR intervengo problemi di progettazione di impacchettamento
e deploying che sono diversi da quelli che individuano i componenti; difatti per gli EAR
sono importanti i problemi di building e Package coupling (vedi [DR8]). In J2EE,
attraverso lo studio dei J2EE Design Pattern (rielaborazione Java dei Design
Pattern), si comprende come progettare e organizzare gli EJB, che possono essere di
vari tipi: Session Bean, Entity Bean, Message Driven Bean, da usare secondo le
esigenze progettuali. Per essi lo standard è la specifica EJB 3.0 che ha semplificato
notevolmente la implementazione degli EJB rendendo lo sviluppo più semplice e snello.

In ambito Microsoft i COM+ sono dei componenti, che rispettano lo standard COM+.

In Tibco, ad esempio, una paletta in BusinessWorks è un componente di basso livello e


general purpose.

Anche un servizio SOA è un componente, che rispetta lo standard in uso dei Web
Service, WSDL etc.

2
Un componente fisico, però, può essere di livello anche più basso: può essere una
libreria di oggetti compilati da riusare, un file di configurazione XML comune a più
applicazioni, un file risorse DEV da aggiungere al compilatore nel progetto (vedi Dev-
C++, Visual C++ etc), un framework da riusare in più progetti (Struts, Spring, AOP,
JADE, etc) etc.

Da qui si comprende che i componenti fisici si presentano a due livelli logici:


 alto livello, dove il componente ha “quasi” un aspetto strutturale/architetturale
nel progetto e le caratteristiche che lo contraddistinguono sono
essenzialmente l’auto-consistenza e la possibilità di essere sottoposto a run
 basso livello, il componente ha un aspetto di risorsa, di framework, di libreria a
oggetti (non eseguibile), un file di configurazione e le caratteristiche che lo
contraddistinguono sono uno scopo “general purpose” e l’impossibilità di essere
sottoposto a run

In quale layer del sistema sono usabili i componenti?


I componenti sono i mattoni di base di una architettura e possono essere usati in:
 Graphical User Interface (GUI)/ Web
 Front-end layer
 Back-end layer
 Db layer.

Essi possono interagire tra loro e con altri componenti built-in come le Topic, le JMS,
le Queue etc.

In ognuno dei layer suddetti un componente può fornire due tipi di servizi:
 Servizi di sistema, soddisfacendo requisiti non funzionali ma necessari
all’architettura, all’usabilità/fruibilità del sistema, alla robustezza, etc.
 Servizi di business

Stati di un componente
Un componente può trovarsi in varie fasi del suo ciclo di vita:
 fase progettuale: si dispone solo della specifica di interfaccia ed è ancora un
componente logico
 fase implementativa: si dispone di un componente fisico implementato
 fase di running: sulla macchina si dispone di una istanza attiva del componente
fisico o parte di essa sollecitata
 fase di testing: si dispone di un componente fisico sottoponibile a run e testato
 fase di deploying: il componente fisico testato è stato installato

3
Architetture di componenti
Un componente può riusare i servizi di altri componenti, incapsulandone il
funzionamento. Ad esempio questo oggi è un punto di forza dell’unione dei concetti
BPM e SOA.

Contratto d’uso
Anche quando si implementa in C, un grande progetto è importante suddividere le
varie parti e parallelizzare su più persone, che poi devono riuscire in breve a integrare
il tutto.

Il componente o i componenti seguono la stessa idea di base: è sufficiente che siano


ben definite le specifiche di interfaccia o contratto d’uso. Questo è un elemento
chiave per una corretta e rapida integrazione tra il componente ed i suoi client.

Le specifiche di interfaccia prevedono:


Operazioni:
 operazioni possibili da chiamare (prototipi, tipi e definizioni) e in che modo
 pre-condizioni da rispettare prima della chiamata per non ricevere errore
 post-condizioni da rispettare lato componente, cosa valorizza come dati a
seguito dell’operazione
 valori di ritorno in caso di errore o di normale funzionamento
Modello delle informazioni:
 la definizione dei vincoli da rispettare
 la definizione di tutte le informazioni da scambiare
 la definizione dello stato che viene memorizzato o meno tra una chiamata e la
successiva di uno stesso client

Il contratto d’uso è definito in fase di analisi/progettazione che nell’Object Oriented


sono fortemente unite, ma è usato a run-time tra client e componente.

Contratto di realizzazione
Il contratto di realizzazione è usato tra la fase di progettazione e implementazione
soltanto. Da le informazioni agli sviluppatori per poter realizzare il componente.

UML e livelli di modellazione dei componenti


Nell’UML quando si realizza un modello che coinvolge un componente esistono almeno
tre livelli di modellizzazione:
 modello concettuale del componente, dove entrano in gioco solo i concetti di alto
livello del dominio di interesse
 modello di specifica, dove si introducono le specifiche di interfaccia; avendo
cioè più una visibilità dell’esterno del componente

4
 modello di implementazione, dove si introducono i dettagli implementativi
interni del componente

E’ da sottolineare che in questa modellazione top-down, una volta arrivati al livello di


specifica, individuato i componenti, le classi etc, si può lavorare a dare flessibilità al
progetto esaminando la possibilità di far introdurre i Design Part e rispettare tutti i
migliori principi dell’Object Oriented.

Processo di sviluppo
I componenti rientrano nei processi Rational Unified Process (RUP), Extreme
Programming (XP), Catalysis etc, ma, qualunque sia il processo scelto, l’obiettivo è di
rispettare ed esaltare le necessità progettuali dei componenti, per poter ottenere la
massima peculiarità possibile secondo le migliori “Best Practices” dell’Object
Oriented.

Nel seguito seguiamo i suggerimenti del processo Catalysis, che è un processo con
focus sui componenti, che lavora a tre livelli di modellazione.

Qualunque sia il processo usato, Catalysis suggerisce che abbiamo sempre la necessità
di disporre di macro-task di lavorazione e all’interno di ognuno di essi devono esistere
dei workflow (insieme di task) capaci di farci produrre dei manufatti o degli elaborati
finiti e nella fattispecie componenti secondo le migliori “Best Practices”.

Per la realizzazione di componenti è chiaramente consigliato un metodo top-down,


partendo dall’architettura dei componenti fino a giungere alle classi necessarie.

Per i componenti avremo la necessità dei seguenti Macro-Task:

5
 Requisiti, con un workflow “Definizione dei requisiti”
 Specifica, dove avremo tre sotto-task e tre workflow che li gestiscono:
o Identificazione dei componenti”
o Interazione tra componenti
o Specifica dei componenti
 Provisioning
 Integrazione

Catalysis esprime ciò graficamente nella figura successiva.

In tutte le fasi di lavorazione è molto importante disporre di strumenti RAD a


supporto di tutti le fasi della metodologia, compresa l’implementazione; strumenti
ovviamente calati sul tipo di tecnologia necessaria a realizzare i componenti: ad
esempio Eclipse o NetBeans per Java NetBeans, Rational Rose per C++/Java, Modeler
Tibco per Tibco, BusinessStudio Tibco, etc.

Sebbene ci aspettavamo vari tipi di macro-task, chiariamo subito che Provisioning può
significare varie cose:
 Acquistare il componente software sul mercato
 Farsi sviluppare il componente software da un vendor
 Farsi prestare da un altro progetto, in base ad un catalogo aziendale, il
componente che ci interessa e che è versionato su uno strumento come SVN,
PCS, CVS, RCS, etc

Il cuore della metodologia per la progettazione del componente è il macro-Task della


Specifica che dettaglieremo nel seguito attraverso un esempio; ma che tuttavia è ben
amalgamata né può far a meno degli altri macro-Task e dei ricicli che possono nascere.
6
Processo di gestione
Il processo di gestione nel ciclo produttivo deve sempre prevedere i futuri
cambiamenti di requisiti, in base alla conoscenza del business della propria azienda, e
mitigare in fase di progettazione i cambiamenti previsti in modo da ridurre gli impatti
di realizzazione e manutenzione futuri: in altri termini “gestire per anticipare il
cambiamento”. Il processo di gestione deve anticipare anche le esigenze di
Provisioning.

Macro-Task Requisiti
Il workflow “Definizione dei requisiti” è realizzabile in ambito UML con:
 Una descrizione testuale del requisito/processo (obbligatorio)
 Un activity diagram, per vedere come si comporta il processo di business e le
responsabilità da attribuire agli attori e le automatizzazioni possibili del
processo
 Un class diagram come modello concettuale del business
 Use case, non sono strettamente necessari

Si lavora a due livelli:


 Fase concettuale di alto livello
 Fase di raffinamento

Ognuno degli strumenti di sopra serve a dare un visione alternativa e utile ed ognuno
deve essere usato solo se utile o se la situazione è complessa e va dettagliata. Si
ritiene obbligatoria la descrizione testuale del requisito.

Facciamo adesso un esempio, che faccia da guida sulla progettazione dei componenti,
su cui applicheremo concetti OO e di UML che riterremo già noti e con cui il lettore,
attraverso i riferimenti, può familiarizzarsi.

Supponiamo che il proprietario di un albergo ci chieda di descrivere e documentare,


come processo di business, le fasi di prenotazione di una camera d’albergo, per poi
decidere insieme la creazione di un sistema software.

Descrizione testuale del processo: il processo è innescato da un cliente, che descrive


il tipo di camera desiderata. Si verifica prima la disponibilità e se la camera è
disponibile si effettua la prenotazione. Una e-mail inoltrata al cliente descriverà tutti
i dettagli della prenotazione. A seguito di questo si possono verificare i seguenti
eventi:
 Il cliente viene alla data prenotata
 Il cliente potrebbe cancellare la prenotazione

7
 Il cliente potrebbe chiedere una modifica della prenotazione e una nuovo inoltro
della e-mail
 Il cliente non si presenta alla data prenotata

Sia che il cliente si presenta o no, c’è un pagamento (una penale nel secondo caso).

Un activity diagram che riassume graficamente la descrizione testuale è presentato


nella figura seguente.

A questo punto serve esprimere i concetti di business coinvolti e quindi occorre un


modello concettuale che rappresentiamo come nella figura successiva.

8
Fin qui abbiamo applicato le solite fasi di analisi dei requisiti tipiche dell’OO e
dell’UML.

Come si vede dai diagrammi precedenti sono stati individuati solo i concetti, non c’è
definizione di interfacce, metodi, dati, responsabilità che sono da individuare nella
fase di raffinamento che vediamo di seguito.

Fase di raffinamento dei requisiti


In questa fase spesso va aggiunta anche la parte non funzionale dei requisiti (basta
solo modificare o serve ad esempio anche cancellare?). In fase di raffinamento vanno
aggiunte anche note su un processo come “manuale” e “automatico”, e “responsabilità
di “ mettendo l’attore coinvolto.

9
Nella figura di sopra abbiamo individuato le responsabilità con delle “swimlane”; ovvero
aree diverse di competenza degli attori. Con “sistema” abbiamo inteso un’area
possibile di automatizzazione. Si poteva scegliere anche diversamente cosa
automatizzare: dipende dal finanziatore innanzitutto e dove possiamo rendere più
rapido e semplice il lavoro dell’albergo.

Nella fase di raffinamento possono sbucare altre esigenze, inizialmente nascoste, e


non funzionali: è importante, in questa fase, trovare i confini dell’applicazione, gli
attori in gioco, il loro ruolo e le loro relazioni.

Ad esempio un “Cliente” può essere un ospite (cioè una persona pagante che non è un
dipendente dell’albergo). Un Addetto alle prenotazioni può essere un dipendente ma
anche un cliente cioè che prenota da Internet; per cui un “Addetto alle prenotazioni”
è un cliente o un dipendente o entrambi. Questi fa nascere il ruolo di Addetto alle
prenotazioni per tenere distinti i ruoli.

Facendo mente locale davanti ad un bel foglio bianco, scriviamo le esigenze dei casi
d’uso, che devono coprire i vari task dell’activity diagram:

1. CreaPrenotazione, che deve coprire Controlla disponibilità, Crea prenotazione,


Conferma prenotazione
2. CancellaPrenotazione, che copre Cancella prenot
3. ModificaPrenotazione, che copre Modifica prenot, Conferma prenotazione
4. ChiudiPrenotazione, che copre Chiudi prenot e Notifica pagamento
5. GestioneArrivoMancato, che copre Gestione arrivo mancato e Notifica
pagamento

10
Se i primi quattro casi d’uso sono chiari, il 5 è evidente che è ambiguo o gli manca
qualcosa (l’ultima che ho detto!). Serve una regola di business da chiedere: ad esempio
“un mancato arrivo è dichiarato tale se il cliente non arriva entro le 8 del mattino
successivo alla prenotazione”. E’ anche evidente che questo evento è legato ad un
tempo e può essere gestito automaticamente dando l’allarme ed è l’Addetto alle
prenotazioni che fa pagare la penale al cliente oppure anche quest’ultimo punto
potrebbe essere automatico (a discrezione o secondo le regole dell’albergo); ma
supponiamo che avvenga manualmente per cui dobbiamo definire un attore
responsabile delle prenotazioni, non sarebbe saggio farlo fare ad un ospite!

Le ultime considerazioni portano ad un diagramma concettuale aggiuntivo sugli attori


come di seguito, che va vagliato opportunamente con il finanziatore del progetto, che
è anche conoscitore del proprio dominio di business.

11
Nell’analisi dovremmo anche “gestire il cambiamento”. Cosa può cambiare? Serve
conoscere bene le esigenze dell’albergo non solo in termini di business ma anche come
andrà evolvendo la vita dell’albergo:
1) L’albergo, se viene ristrutturato, può aumentare il numero di camere e cambiare
il tipo di camere; per cui meglio prevedere funzionalità per le camere: Aggiungi,
Modifica, Rimuovi e per il Tipo (Aggiungi, Modifica, Rimuovi)
2) Un cliente può cambiare indirizzo (Modifica Indirizzo)
3) Un cliente può essere cancellato (a discrezione del Responsabile)
4) I dipendenti possono essere aggiunti, modificati e cancellati (da un
Responsabile)

Un’altra cosa importante è di estrarre dagli use case gli “aspetti comuni”, trasversali
di <<include>>.

Ad esempio CancellaPrenotazione, ModificaPrenotazione, ChiudiPrenotazione hanno un


aspetto comune: occorre identificare la prenotazione creata; per cui c’è un use case
comune.

Gli aspetti comuni sono aspetti general purpose e incentivano al riuso nel progetto.
Esistono anche aspetti trasversali architetturali (requisiti non funzionali) di questo
tipo e coadiuvati anche dalle tecnologie, come l’Aspect Oriented Programming (AOP) in

12
Java; il che migliora la manutenibilità di un progetto, incrementando la produttività e
riducendo i bug.

Analisi delle relazioni del Modello concettuale


Conviene sempre fare anche l’analisi delle Relazioni del Modello concettuale per
evitare sorprese inaspettate.

Albergo-Camera: una Camera fa parte solo dell’albergo e non di un altro albergo.

Albergo-Dipendente: un dipendente potrebbe essere assunto, andare in


pensione/licenziato, oppure potrebbe essere necessario modificare i suoi dati per cui
è giusto avere funzionalità di aggiunta, modifica, cancellazione per i dipendenti.
Nell’esempio si ipotizza l’esistenza almeno di 1 dipendente (cioè nei casi minimi c’è una
persona che copre più ruoli).

Albergo-Cliente: è una relazione di non interesse. L’unico elemento comune tra


Albergo e Cliente è la prenotazione.

13
Albergo-Prenotazione: è una relazione importante. La Prenotazione è una entità di
business cruciale attorno cui si sta creando il sistema e la cosa qui importante è che
una prenotazione “può” essere cambiata.

Cliente-Indirizzo: ci può essere modifica di un indirizzo ed il Cliente ne può dare solo


uno, quello che ritiene principale o importante in quel momento ai fini della
prenotazione

Prenotazione-Tipo Camera: è importante. Una prenotazione concorda un solo tipo di


camera, ma potrebbe cambiare l’esigenza del tipo di camera e cambiare la
prenotazione

Prenotazione-Conto: non è essenziale si potrebbe anche eliminare, per il discorso che


stiamo facendo.

Prenotazione-Camera: importante. Una prenotazione richiede una camera di un certo


tipo. L’assegnazione di solito però avviene all’arrivo del cliente.

Conto-Pagamento: non necessario, perché fuori dal confine del sistema. Interessa i
sistemi di carta di credito ad esempio. In altri termini il pagamento o il conto è
ritenuto chiuso manualmente a seguito della trasmissione dei dati via telematica ad un
sistema di carta di credito.

TipoCamera – Camera: non può cambiare questa relazione se non cambia la camera. Una
singola non diventa magicamente una doppia se anche la camera non cambia
fisicamente per ristrutturazione.

Qualità del servizio


Tra i requisiti non funzionali a questo punto è essenziale prevedere alcuni tipici:
sicurezza (username/password da Internet e protocolli sicuri HTTPS e SSL),
affidabilità del sistema, database e prestazioni. A seconda di cosa si decide qua
possono apparire altre cose che arricchiscono il dominio della soluzione.

Descrizione testuale dei casi d’uso


In questa fase è fondamentale scrivere le descrizioni testuali e si invita di esplicitarle
gli use case.

Descrizione testuale del Caso d’uso “CreaPrenotazione”


Attore : Addetto alle prenotazioni
Scopo : Prenotare una camera d’albergo

14
Scenario principale
1) L’addetto alle prenotazioni chiede al sistema di fare una prenotazione
2) L’addetto seleziona albergo, data e tipo di camera
3) Il sistema fornisce prezzo all’addetto
4) L’addetto chiede di prenotare una stanza
5) L’addetto fornisce nome e C. A. P.
6) L’addetto fornisce un indirizzo e-mail come recapito
7) Il sistema istanzia la prenotazione e gli associa una etichetta
8) Il sistema fornisce l’etichetta all’addetto
9) Il sistema crea un messaggio di conferma e lo inoltra per e-mail al recapito

Estensioni
3) Se la stanza non è disponibile il sistema offre delle alternative all’addetto che può
sceglierne una a cui può seguire
3a) L’addetto lascia stare e desiste dalla prenotazione
3b) L’addetto scegli l’opzione e prosegue
6) Se l’indirizzo e-mail è presente è individuato da nome e CAP e non occorre inserirlo

Descrizione testuale del Caso d’uso “IdentificaPrenotazione”


Attore : varia
Scopo : Sempre incluso

Scenario principale
1) L’attore fornisce l’etichetta della prenotazione
2) Il sistema identifica la prenotazione

Estensioni
2) Il sistema non trova la prenotazione con l’etichetta
2a) L’attore fornisce nome e CAP
2b) Il sistema identifica l’ospite e fornisce la lista delle prenotazioni attive
2c) L’ospite seleziona la prenotazione giusta
2d) Stop
2) La prenotazione si riferisce ad un altro albergo
2a) fallimento
2) Non ci sono prenotazioni attive
2a) Fallimento

Descrizione testuale del Caso d’uso “ChiudiPrenotazione”


Attore : Ospite
Scopo : Fare il check in

Scenario principale
15
1) L’ospite arriva in albergo e chiede della prenotazione
2) Includi IdentificaPrenotazione
3) L’ospite conferma la data, la durata e il tipo di stanza
4) Il sistema assegna la stanza
5) Il sistema notifica al sistema di pagamento che c’è un nuovo cliente

Estensioni
3) Il sistema non identifica la prenotazione con l’etichetta
3a) Fallimento

Workflow “Identificazione dei componenti” (WIC) – Macro-Task Specifica


E’ il workflow più importante e cuore della progettazione dei componenti, per cui va
dedicata molta attenzione e cura per ottenere il massimo vantaggio.

L’obiettivo di questo workflow è di:


 Creare un primo modello di specifiche di interfacce e di componenti in modo da
creare una prima architettura a componenti di base
 Le successive fasi saranno di raffinamento del modello a componenti di
partenza

In input al Workflow WIC abbiamo:


 Modello concettuale di business
 Activity Diagram
 Use case

I vincoli al Workflow WIC sono:


 Interfacce preesistenti
16
 Risorse preesistenti
 Pattern architetturali che si vogliono realizzare

Gli output che si vogliono ottenere sono:


 Interfacce di sistema
 Modello di business
 Interfacce di business
 Specifiche dei componenti e architettura

Il WIC si occupa, quindi, di far interagire Input-Vincoli per ottenere gli Output,
vediamo come nel seguito.

Identificare le interfacce nel WIC


Sappiamo che le interfacce sono di due tipi:
 Interfacce di sistema
 Interfacce di business

Le interfacce di sistema emergono dall’analisi degli use case e dall’attivazione di


questi ultimi da parte di attori. In altri termini dipendono dalla interazione degli
attori col sistema. Solitamente ciò porta a comprendere che serve una GUI o una
interfaccia Web e, quindi, si progetta in modo da gestire gli Use case visti. Le
interfacce di business, invece, sono legate al modello concettuale di business.

Identificare le Interfacce di sistema nel WIC


Per ogni caso d’uso devo avere, in prima approssimazione, almeno una interfaccia
(interface) e per ogni interfaccia delle operazioni possibili da fare su essa, come
nell’esempio.

Dopo questa prima fase si deve prendere ogni use case e verificare se ci sono delle
responsabilità da modellare. Se si individuano responsabilità occorre rappresentarle
con delle operazioni in una o più interfacce (interface) opportune.

Sono, quindi, fondamentali le descrizioni testuali dei casi d’uso in questa fase ed
esaminiamo innanzitutto gli scenari di successo.

Use case CreaPrenotazione – Scenario di successo: al passo 2 il sistema deve fornire


all’addetto una lista di alberghi, poi col passo 3 a seguito della selezione di un albergo
deve fornire i dettagli di prezzo e disponibilità. Le operazioni associate potremmo
chiamarle getDettagliAlbergo() e getInfoCamera(). A seguito della consultazione delle
informazioni, al passo 7 l’Addetto fa la prenotazione con creaPrenotazione() fornendo
in input i dati e l’operazione deve restituire l’etichetta.

17
Use case ChiuderePrenotazione – Scenario di successo: al passo 3 del check-in il
cliente esibisce l’etichetta della prenotazione. Per cui serve un getPrenotazione(), poi
si deve allocare una stanza e confermare il periodo di permanenza; per cui serve un
metodo inizioPermanenza(), che segnerà la data di inizio e il periodo di permanenza.

Finora non abbiamo definito i parametri. Lo faremo quando avremo una maggiore
visibilità nella fase di interazione; questo perché stiamo lavorando ancora a livello di
astrazione maggiore o a livello concettuale alto.

Identificare le Interfacce di business nel WIC

Per individuare le interfacce di business è necessario:


1) Produrre un modello di business, raffinamento del modello concettuale e calato
sul sistema e evidenziazione dei vincoli
2) Specificare le regole di business
3) Identificare i Tipi di dati di business di base per le interfacce
4) Creare interfacce di business per ogni tipo di dato di business
5) Aggiungere le responsabilità al modello

Per il punto 1) dobbiamo ritornare al modello concettuale e raffinarlo. Vediamo cosa


Eliminiamo alcune cose, perché il livello di astrazione sul problema fatto
precedentemente ci suggeriva:
 Eliminare Conto
 Eliminare Pagamento
 Eliminare Indirizzo, perché l’anagrafica dei clienti potrebbe essere fatta a
parte, rispetto alla gestione delle prenotazioni
 Dipendente non ci serve se abbiamo L’Addetto alle prenotazioni.

In più aggiungiamo i dati e il tipo.

18
Assicurarsi che le molteplicità siano corrette e se esistono tutte le dipendenze. Sopra
abbiamo aggiunto anche la relazione tra Albergo e Tipo Camera.

Per il punto 2) sono evidenziati tre regole di business con le note.


Il punto 3) è delicato. Cosa vuol dire identificare i tipi di dati di business di base per
le interfacce?

Significa:
1) identificare i tipi del dominio,
2) che sono indipendenti, ovvero senza associazioni obbligatorie (un 1 come minimo dal
lato opposto dell’associazione)
3) non sono di un tipo “categorizzante”. Categorizzante è un tipo che fa una
classificazione di altri tipi

Esaminiamo il dominio di business ottenuto. Camera potrebbe non essere un tipo base
perché TipoCamera la categorizza. Sicuramente Camera ha una associazione
obbligatoria con Albergo (C’è l’1) per cui Camera è da scartare dai tipi base per
l’interface.

Mentre Albergo e Cliente possono essere tipi base per le interfacce per le te regole
che ci siamo fissati.

Adesso dobbiamo affrontare punto 4) e 5); la regola è creare una interfaccia di


business per ogni tipo base trovato. Abbiamo due tipi base per cui servono due
interface di business, che modelliamo sul modello di business direttamente.

19
Al modello abbiamo aggiunta anche una navigabilità da Prenotazione a Cliente. Questo
vuol dire che essendo Cliente indipendente è Prenotazione che fa riferimento a
Cliente e ciò lo evidenzia maggiormente nel modello di business; ma attenzione questo
vuol dire anche che sarà l’interfaccia IHotelMgt a registrare il Cliente tramite
Prenotazione.

Nella progettazione a componenti è una “Best Practices” il fatto di ridurre al minimo


necessario le dipendenze.

Specifiche iniziali delle interfacce


Le interfacce di sistema non vanno nel modello di business. A questo punto conviene
identificare i package in cui inserire le varie cose.

Una idea progettuale della suddivisione in package degli artefatti che produciamo è la
seguente:

Package Specifiche che conterrà


 Modello del tipi di business e dati di business, derivato dalle interfacce di
business
 Specifiche di interfaccia, che conterrà a sua volta:
o Interfacce di sistema
o Interfacce di business
20
A questo punto occorre completare l’ultimo passo del WIC.

Specifiche dei componenti e architettura


Serve un componente per ogni specifica di interfaccia. In pratica per l’esempio in
corso avremo due componenti per le specifiche di interfaccia di sistema:
 Componente Sistema di prenotazioni che offre l’interfaccia con i metodi
iCreaPrenotazione e iChiudiPrenotazione e richiama i componenti di sistema e di
Business: IPagamenti, ICustomerMgt, IHotelMgt
 Componente Sistema pagamenti che offre l’interfaccia col metodo IPagamenti

Avremo, poi, per l’esempio due componenti per le specifiche di business:


 Componente CustomerMgt, che offre l’interfaccia ICustomerMgt,
 Componente HotelMgt, che offre l’interfaccia IHotelMgt
 Componente Sistema pagamenti che offre l’interfaccia col metodo IPagamenti

Quindi l’architettura a componenti è la seguente:

Con questo abbiamo completato il Workflow “Individuazione componenti” (WIC);


difatti abbiamo individuato i componenti, l’architettura e il modello di business.

Workflow di Interazione tra componenti (WITC)


Questo workflow si pone l’obiettivo di individuare i prototipi dei metodi, i tipi, gli input
e gli output sostanzialmente per ogni componente e in base all’interazione tra
componenti.

Si può usare una tecnica di modellazione comportamentale, visto che il workflow si


concentra sul cosa deve fare il componente e come interagisce con gli altri.
21
In input al WITC abbiamo le interfacce di sistema e di business, il modello di
business, i componenti e l’architettura.

In output dobbiamo ottenere in output un affinamento dell’interazione


comportamentale dei componenti, in sostanza le interfacce definitive e complete di
ogni componente dell’architettura.

Durante questa fase non si deve escludere la possibilità di individuare dei pattern
comuni e di operazioni generali che rimpiazzano quelle dedicate, incentivando il riuso.

Per applicare il metodo dobbiamo prendere in esame ogni componente e i suoi metodi
finora individuati.

Metodo getDettagliAlbergo() del componente Sistema prenotazioni


Sappiamo che il metodo deve fornire una lista di alberghi da cui l’Addetto può
scegliere, a fronte di un input anche parziale del nome dell’albergo desiderato.
Inserendo cioè una stringa parziale verranno fuori tutti gli alberghi il cui nome inizia
per quella stringa e verranno visualizzate le info relative, con un identificativo unico
dell’albergo. Poiché sono informazioni correlate, qui si decide che verranno mostrati
per ogni albergo: l’IdAlbergo, il nome, una lista di tipi camera; per cui conviene che
tutto ciò sia una struttura dati apposita di tipo DettagliAlbergo, che contenga
l’IdAlbergo, nome e tipiCamera[] e il metodo deve restituire una lista di
DettagliAlbergo, per ogni albergo.

Il metodo quindi diventa


ICreaPrenotazione::getDettagliAlbergo(in corrisp:String): DettagliAlbergo []
22
Ora dobbiamo guardare l’interazione tra il componente Sistema prenotazioni e il
componente HotelMgt; questo ci porta subito a dire che anche HotelMgt nella sua
interfaccia deve avere il metodo getDettagliAlbergo.

Metodo getInfoCamera() del componente Sistema prenotazioni


Anche qui occorre passare in input un elemento di tipo DettagliAlbergo (l’albergo
scelto) e ricevere in output la disponibilità (boolean) e il prezzo.

Il metodo quindi diventa


ICreaPrenotazione::getinfoCamera(in info:DettagliAlbergo,
out disp:Boolean,
out prezzo:Integer
)

Tale metodo deve allora esistere anche nell’interfaccia del componente HotelMgt.

Metodo creaPrenotazione() del componente Sistema prenotazioni


Il metodo deve creare la prenotazione e notificare la cosa via email al cliente. Il
metodo deve riuscire a riconoscere la prenotazione fatta e il cliente, quindi gli
servono in input udue strutture dati:
 struttura dati Dettagli Prenotazione che conterrà l’idAlbergo di tipo Integer,
tipoCamera (String) e date di tipo intervallo Date;
 struttura dati DettagliCliente che conterrà nome (String), CAP[0..1], e-
mail[0..1]
Con [0..1] intendiamo o non c’è oppure esiste almeno 1.

In output deve restituire una etichetta della prenotazione (String). Poi dobbiamo
gestire un valore Integer di ritorno per gestire lo status cioè se le cose sono andate
OK oppure no; ad esempio 0=OK, 1 il cliente non esiste e non si è potutto aggiungere
perché manca CAP e e-mail, 2=non c’è CAP e il nome corrisponde a più clienti

Il metodo quindi diventa


ICreaPrenotazione::crePrenotazione(in pren:DettagliPrenotazione,
in cli: DettagliCliente,
out etic:String
): Integer

Quindi l’interfaccia HotelMgt deve avere questo metodo. Però abbiamo anche
compreso che dobbiamo anche riconoscere il Cliente (responsabilità di CustomerMgt)
e ci serve un altro metodo:

23
iCustomerMgt::getClienteCorrispondente( in cli: DettagliCliente, out idC: ClientId):
Integer

Abbiamo deciso di ricevere un id del cliente in output e uno status che corrisponde a:
0=OK, 1=Non esiste, 2=Non c’è CAP o email

Serve a questo punto un altro metodo quello di notifica al cliente (quindi


responsabilità di CustomerMgt):riceve l’id del cliente e una stringa di informazione di
conferma per cui il metodo è:

iCustomerMgt::notificaCliente( in idC: ClientId, in s: String): Integer

Notare che abbiamo deciso di passare gli id del cliente sia a HotelMgt che
CustomerMgt ed è responsabilità del component Sistema Prenotazioni di produrli, in
questo modo non c’è interdipendenza tra HotelMgt e CustomerMgt e sono riusabili
anche in altri contesti.

Responsabilità emerse finora


ICreaPrenotazione delega la creazione della prenotazione a IHotelMgt ma gestisce le
associazioni col cliente.
iHotelMgt è responsabile delle camere, dei tipi di camera, di associare i tipi camere e
i prezzi alle prenotazioni.
iCustomerMgt è responsabile dei clienti e dei loro dettagli e della gestione delle
notifiche ai clienti.

Vincoli architetturali di numerosità dei componenti


Finora non abbiamo ancora detto nulla sulla numerosità di tali componenti.

Però se avessimo ad esempio due CustomerMgt ognuno che agisse su un insieme


diverso di clienti avremmo il problema dell’id del cliente che non sarebbe univoco e lo
stesso con HotelMgt. Per cui questo è un vincolo. Possiamo avere più Sistemi di
prenotazioni ma un solo HotelMgt, e un solo CustomerMgt. Per cui per come abbiamo
progettato le cose in questo esempio esiste tale vincolo.

Integrità referenziale
Abbiamo visto che HotelMgt registra le identità dei clienti (gli idClient) come parte
della prenotazione. Che succede se cancelliamo un cliente?

In poche parole i riferimenti inter-componente devono rimanere sempre validi.

In generale esistono varie soluzioni che elenchiamo:

24
 assegnare le responsabilità d un solo componente. Nel nostro esempio vorrebbe
dire che tutte le cancellazioni di cliente devono essere gestite da HotelMgt per
aggiustare le cose sulla prenotazione (probabilmente da eliminare) e poi passata a
CustomerMgt per la cancellazione del Cliente
 assegnare la responsabità a chi è owner della cancellazione, quindi a CustomerMgt
che poi dovrebbe attivare HotelMgt (meccanismo ad esempio Publish-Subscribe
detto anche Observer) per aggiustare le cose
 assegnare la responsabilità ad un componente gestore (Sistema prenotazioni) che
quando cancella il cliente su CustomerMgt va ad aggiustare le cose su HotelMgt
 si può proibire la cancellazione finchè la prenotazione è attiva

Nel nostro esempio la prima opzione non funziona, per la dipendenza che abbiamo
scelto, anche perché vogliamo mantenere indipendenti HotelMgt e CustomerMgt.
L’ultima non risolve niente perché quando la prenotazione non è attiva rimane il
problema. Tra seconda e terza opzione è più semplice la terza.

Se usiamo la terza opzione allora nel componente Sistema di prenotazioni è


necessario:

il metodo cancella Cliente(in idC:ClientId): Integer

ed esso deve essere presente anche in CustomerMgt.

Completare i metodi rimanenti

Servono ancora:
iCustomerMgt::creaCliente(in cli: String, out id:Integer)
se un nuovo cliente crea la prenotazione

A causa di ChiudiPrenotazione ci serve anche:


iHotelMgt::getPrenotazione(in etich:String, out det:DettagliPrenotazione,
out:DettagliCliente): Boolean
qui il boolean è false se la prenotazione non viene trovata

Raffinare e fattorizzare le interfacce


Questa fase può essere utile. Fattorizzare le interfacce significa suddividere i tipi
su più interfacce in modo di avere responsabilità uniche e coerenti e possibilmente
generali. Qui l’obiettivo NON è gestire il cambiamento, perché si possono
facilmente aggiungere interfacce eventualmente. Il nostro esempio era abbastanza
semplice e tale fase non è necessaria.

25
Specifica dei componenti
L’ultima fase del WITC.

In questa fase vanno riviste tutte le operazioni e i dati scambiati, i vincoli, le


regole di business, pre-condizioni, post-condizioni e gli invarianti.

Le pre-condizioni prima di chiamare il metodo offerto da un componente affinchè


la chiamata sia valida e le post-condizioni offerte dopo la chiamata al metodo e con
pre-condizione rispettata affinchè il client operi correttamente sui dati ritornati.
Infine se ci sono invarianti (un vincolo associato ad un tipo e vero sempre), ad
esempio tra Prenotazione e Cliente c’è un invariante perché ogni prenotazione deve
essere associata ad un solo cliente.

Per avere idee chiare su pre-condizioni e post-condizioni può essere utile fare una
istantanea (tecnica snapshot o di debugger logico) prima e dopo delle istanze
tramite dei diagrammi e comprendere i cambiamenti di stato oppure ragionando
sui valori assunti prima e dopo a partire dai metodi.

Workflow Provisioning
E’ una fase opzionale, da usare se necessaria. Si tratta di avere le idee chiare, di
solito dopo la progettazione, su quale componente tecnologico ad alto contenuto di
know-how occorre investire come acquisto sul mercato o farsi prestare perché già
disponibile in azienda.

Workflow di Integrazione
Il workflow di Integrazione diventa notevolmente importante se è necessario il
workflow di Provisioning.
26
Occorre analizzare bene cosa si va ad acquistare come componente: i metodi e i
dati offerti, la tecnologia, il linguaggio, i vincoli, le regole di business, pre-
condizioni e post-condizioni, per essere certi che sia integrabile e riusabile
nell’ambito del proprio progetto. Inoltre va valutato anche se il riuso ottenuto o il
know-how eventualmente assente riesce a giustificare il costo sostenuto.

Buon Lavoro

RIFERIMENTI

[DR1] Martin Fowler – UML Distilled – Prima edizione italiana


[DR2] Rosario Turco – Concetti di base Object Oriented
[DR3] Rosario Turco – Principi di Disegno
[DR4] Rosario Turco – Usabilità e ripetibilità dei processi produttivi software
[DR5] Rosario Turco – Modellare con l’UML ed i colori
[DR6] Rosario Turco – Risoluzione di problemi con UML
[DR7] Rosario Turco – Tradurre le relazioni UML in C++
[DR8] Rosario Turco - Refactoring: la teoria in pratica
[DR9] Rosario Turco – Disegno per il riuso e con il riuso
[DR10] Robert C. Martin – Design Principles and Design Patterns
[DR11] Gamma, Helm, Johnson,Vlissides – Design Patterns – Elementi per il riuso di software
a oggetti – Prima edizione italiana
[DR12] Rosario Turco - OO - Design Pattern-e-book
[DR13] Rosario Turco – Framework e UML
[DR14] Rosario Turco – Il Business AS IS Modeling con UML
[DR15] Kent Beck – Programmazione estrema – Introduzione
[DR16] Rosario Turco – Extreme Programming
[DR17] Rosario Turco – Rational Unified Process
[DR18] Rosario Turco – BPM, SOA e Business Rules Engine, l’ultima frontiera
[DR19] John Cheesman, John Daniels – UML Components
[DR20] Catalysis http://www.catalysis.org/

27

You might also like