Professional Documents
Culture Documents
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.
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+.
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.
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.
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.
4
modello di implementazione, dove si introducono i dettagli implementativi
interni del componente
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”.
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
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
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
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.
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).
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.
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.
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:
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!
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>>.
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.
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.
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.
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
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
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
Il WIC si occupa, quindi, di far interagire Input-Vincoli per ottenere gli Output,
vediamo come nel seguito.
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.
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.
18
Assicurarsi che le molteplicità siano corrette e se esistono tutte le dipendenze. Sopra
abbiamo aggiunto anche la relazione tra Albergo e Tipo Camera.
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.
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.
Una idea progettuale della suddivisione in package degli artefatti che produciamo è la
seguente:
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.
Tale metodo deve allora esistere anche nell’interfaccia del componente HotelMgt.
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
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
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.
Integrità referenziale
Abbiamo visto che HotelMgt registra le identità dei clienti (gli idClient) come parte
della prenotazione. Che succede se cancelliamo un cliente?
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.
Servono ancora:
iCustomerMgt::creaCliente(in cli: String, out id:Integer)
se un nuovo cliente crea la prenotazione
25
Specifica dei componenti
L’ultima fase del WITC.
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
27