I sottosistemi possono essere utilizzati in diversi modi
complementari per suddividere il sistema in unità che
-
possono essere ordinati, configurati o prodotti in modo indipendente
-
possono essere sviluppati in modo indipendente, purché le interfacce restino immutate
-
possono essere distribuiti in modo indipendente in un insieme di nodi di computazione distribuiti
-
possono essere modificati in modo indipendente senza danneggiare altre parti dei sistemi
Quindi i sottosistemi sono ideali per la modellazione dei componenti (unità sostituibili di assemblaggio in uno
sviluppo basato su componenti) più grandi di una singola classe di progettazione.
Inoltre i sottosistemi possono
-
suddividere il sistema in unità che possono fornire una sicurezza limitata sulle risorse chiave
-
rappresentare nella progettazione i prodotti esistenti o i sistemi esterni.
Una classe di analisi complessa viene mappata ad un sottosistema di progettazione se questo sembra rappresentare un
comportamento che non sia la responsabilità di una classe di progettazione singola che agisca indipendentemente. E'
anche possibile che una classe di progettazione complessa diventi un sottosistema, se verosimilmente viene implementata
come un insieme di classi che collaborano.
I sottosistemi sono inoltre un buon mezzo per identificare le parti del sistema da sviluppare indipendentemente con un
team separato.Se gli elementi della progettazione possono essere contenuti completamente all'interno di un pacchetto
insieme alle relative collaborazioni, un sottosistema è in grado di fornire un modulo più forte di incapsulamento di
quello fornito da un pacchetto semplice. Il contenuto e le collaborazioni all'interno di un sottosistema sono
completamente isolati dietro una o più interfacce, in modo che il client del sottosistema dipenda solo
dall'interfaccia. Il progettista del sottosistema viene quindi completamente isolato dalle dipendenze esterne; al
progettista (o al team di progettazione) viene richiesto di specificare la modalità di realizzazione dell'interfaccia,
ma è completamente libero di modificare la progettazione interna del sottosistema senza implicazioni per le dipendenze
esterne.In grandi sistemi con team principalmente indipendenti, questo grado di separazione insieme all'applicazione
strutturale fornita dalle interfacce formali, è una valida argomentazione per scegliere i sottosistemi oltre ai
pacchetti semplici.
Il sottosistema di progettazione viene utilizzato per incapsulare queste collaborazioni in modo tale che i client del
sottosistema siano completamente ignari della progettazione interna del sottosistema, anche nel caso in cui utilizzino
i servizi da esso forniti. Se i sottosistemi/classi che partecipano in una collaborazione interagiscono solo per
produrre una serie di risultati ben definiti, è possibile incapsulare la collaborazione e gli elementi di progettazione
relativi all'interno del sottosistema.
E' possibile applicare questa regola anche ai sottoinsiemi delle collaborazioni. E' sempre possibile incapsulare e
semplificare sia una parte che tutta una collaborazione al fine di rendere più semplice la comprensione della
progettazione.
Suggerimenti
Suggerimento
|
Dettagli
|
Ricercare opzioni
|
Se una collaborazione particolare (o una collaborazione secondaria) rappresenta un comportamento
facoltativo accluderla ad un sottosistema. Le funzioni che è possibile rimuovere, aggiornare o
sostituire con alternative verranno considerate indipendenti.
|
Visualizzare interfaccia utente del sistema.
|
Se l'interfaccia utente è relativamente indipendente dalle classi di entità nel sistema (ad es.
entrambe sono in grado e si modificheranno indipendentemente), creare sottosistemi integrati
orizzontalmente: le classi boundary d'interfaccia utente relative al gruppo insieme in un sottosistema
e le classi entità relative al gruppo in un altro sottosistema.
|
Se l'interfaccia utente e le classi di entità in essa visualizzate sono fermamente unite (ad es. una
modifica all'una attiva una modifica all'altra), creare sottosistemi verticalmente integrati: inserire
le classi di entità e le classi boundary relative in sottosistemi comuni.
|
Visualizzare attori
|
Separare la funzionalità utilizzata da due diversi attori, in modo che ogni attore sia in grado di
modificare indipendentemente i requisiti sul sistema.
|
Creare i sottosistemi per incapsulare l'accesso ad un sistema o ad un'unità esterni.
|
Ricercare accoppiamento e coesione tra elementi di progettazione
|
I sottosistemi/classi fortemente accoppiati o coesivi collaborano per fornire alcune serie di servizi.
Organizzare gli elementi fortemente accoppiati in sottosistemi e separare gli elementi lungo le righe
di accoppiamento debole. In alcuni casi, è possibile eliminare interamente l'accoppiamento debole
suddividendo le classi in classi più piccole con più responsabilità di coesione oppure ripartendo i
sottosistemi in modo appropriato.
|
Controllare sostituzioni
|
Se esistono diversi livelli di servizio specificati per una capacità particolare (ad esempio:
disponibilità elevata, media e bassa), rappresentare ciascun livello di servizio come un sottosistema
separato, ciascuno dei quali realizzerà lo stesso insieme di interfacce. In questo modo,i sottosistemi
saranno sostituibili.
|
Controllare distribuzione
|
Sebbene
possano esistere più istanze di un sottosistema particolare, ciascuna in esecuzione su nodi diversi, in
molte strutture non è possibile suddividere una singola istanza di un componente sui nodi. Nei casi in
cui è necessario suddividere il comportamento del sottosistema sui nodi, si consiglia di scomporre il
sottosistema in sottosistemi più piccoli (in modo che ciascuno rappresenti un singolo componente) con
funzionalità più limitate.
Determinare la funzionalità che è necessario risieda su ciascun nodo e creare un nuovo sottosistema a
cui 'appartenga' tale funzionalità, distribuendo le responsabilità e gli elementi relativi del
sottosistema originale in modo appropriato.
I sottosistemi nuovi sono interni ai sottosistemi originali.
|
Una volta organizzata la progettazione in sottosistemi, aggiornare le realizzazioni del caso d'uso di conseguenza.
I sottosistemi di progettazione vengono modellati utilizzando i componenti UML. Tale costruzione fornisce le seguenti
capacità di modellazione:
-
può raggruppare le classi per definire una parte di granularità più ampia di un sistema
-
può separare le interfacce visibili dall'implementazione interna
-
può disporre dell'esecuzione al run-time
Altre considerazioni:
-
E' necessario che ogni sottosistema di progettazione venga fornito di nome e di una breve descrizione.
-
E' necessario trasferire le responsabilità della classe di analisi originale al sottosistema appena creato,
utilizzando la descrizione del sottosistema per documentare le responsabilità
Nota: UML 2.0 definisce inoltre uno stereotipo per componente denominato <<subsystem>>, che indica che può
essere utilizzato, per rappresentare le strutture su larga scala. Un sottosistema di progettazione RUP potrebbe o non
potrebbe essere una struttura si larga scala; entrambi sono sottosistemi di progettazione dalla prospettiva RUP. Questa
è una decisione che deve prendere l'architetto di software (se scegliere ad esempio, di etichettare i componenti
composti di componenti come <<subsystem>>).
Se un prodotto esistente esporta le interfacce, ad es. operazioni(e forse ricezioni), ma mantiene tutti i dettagli dell'implementazione nascosti,
allora potrebbe essere modellato come sottosistema nella vista logica. Esempi di prodotti utilizzati dal sistema
che è possibile rappresentare con un sottosistema:
-
Software di comunicazione (middleware).
-
Supporto di accesso al database (Supporto mappatura RDBMS).
-
Prodotti specifici dell'applicazione.
Alcuni prodotti esistenti quali le collezioni di tipi e le strutture di dati (ad es. stack, elenchi, code) potrebbero
essere rappresentati in modo migliore come pacchetti, poiché rivelano più del comportamento ed è il contenuto
particolare del pacchetto che è importante e non il pacchetto in sé, che è un semplice contenitore.
I programmi di utilità comuni, come le librerie di matematica, potrebbero essere rappresentati come sottosistemi, se
esportano semplicemente le interfacce, ma se questo sia necessario o abbia un senso dipende dal giudizio del
progettista sulla natura dell'elemento modellato. I sottosistemi sono costruzioni orientate all'oggetto (in
quanto componenti modellati): un sottosistema può disporre di istanze (se indicato dal progettista). UML fornisce un
altro modo per modellare i gruppi di variabili globali e le procedure nel programma di
utilità, che è uno stereotipo di classe - il programma di utilità non dispone di istanze.
Quando si definisce il sottosistema per rappresentare il prodotto, definire anche una o più interfacce per
rappresentare le interfacce del prodotto.
I sottosistemi di progettazione (modellati some componenti UML) differiscono dai pacchetti nella semantica relativa: un
sottosistema fornisce un comportamento tramite la realizzazione di una o più interfacce. I pacchetti non forniscono
comportamento; sono semplicemente contenitori di elementi che forniscono comportamento.
Il motivo per utilizzare un sottosistema invece di un pacchetto è che i sottosistemi incapsulano il contenuto, fornendo
il comportamento solo tramite le interfacce relative. Il vantaggio è che, diversamente che in un pacchetto, il
contenuto ed i comportamenti interni di un sottosistema possono essere modificati con la massima libertà finché le
interfacce del sottosistema rimangono costanti. I sottosistemi forniscono inoltre un elemento di 'progettazione
sostituibile': ogni due componenti di <<realizzazione>> che realizzano le stesse interfacce(o componente di
<<specifica>>) sono intercambiabili.
Per assicurare che i sottosistemi siano elementi sostituibili nel modello, è necessario applicare poche regole:
-
E' necessario che un sottosistema minimizzi l'esposizione del contenuto relativo. Idealmente nessun elemento
contenuto da un sottosistema dovrebbe avere visibilità 'pubblica' e perciò nessun elemento al di fuori del
sottosistema dipende dall'esistenza di un elemento particolare al suo interno. Alcune eccezioni:
-
In alcune tecnologie, è impossibile modellare gli elementi esterni di un'interfaccia UML. Ad esempio,
un'interfaccia Java viene modellata come una classe stereotipata.
-
La progettazione di un sottosistema potrebbe richiedere l'esposizione di classi piuttosto che delle
interfacce UML. Ad esempio, è possibile utilizzare una classe "delegate" o "access" per nascondere una
collaborazione complessa di altre classi. Mentre è possibile utilizzare un pacchetto ordinario come
sostituzione, un sottosistema può essere utilizzato per enfatizzare l'intento di incapsulare il
comportamento e nascondere i dettagli interni.
-
Quando gli elementi esterni del sottosistema non sono interfacce UML, è spesso di aiuto disporre di un diagramma
(ad esempio denominato "Vista esterna") che visualizzi gli elementi visibili del sottosistema.
-
E' possibile che un sottosistema definisca le dipendenze relative su interfacce di sottosistema (e elementi
pubblicamente visibili del sottosistema nei casi eccezionali sopra descritti). Inoltre, è possibile che un numero
di sottosistemi condivida un insieme di interfacce o di definizioni di classe in comune, nel qual caso tali
sottosistemi 'importeranno' il contenuto dei pacchetti che contengono gli elementi comuni. Ciò avviene più
comunemente con pacchetti che si trovano nei livelli bassi della struttura, per garantire che le definizioni comuni
delle classi che è necessario spostare tra i sottosistemi, vengano definite consistentemente.
Segue un esempio di dipendenze pacchetto e sottosistema:
dipendenze pacchetto e sottosistema nel modello di progettazione
L'UML ([UML04]) definisce:
Esiste un numero di stereotipi UML standard da applicare al componente ad es. <<specifica>> e
<<realizzazione>> per modellare i componenti con definizioni di realizzazione e specifica distinte,
dove una specifica può avere più realizzazioni.
Un componente stereotipato per <<specifica>> specifica un dominio di oggetti senza definire
l'implementazione fisica di tali oggetti. Avrà solo fornito e richiesto interfacce e non è previsto che disponga di
alcuna classe di realizzazione e componente secondario come parte della definizione relativa.
Un componente stereotipato per<<realizzazione>> specifica un dominio di oggetti e inoltre definisce
l'implementazione fisica di tali oggetti. Ad esempio, un componente stereotipato da <<realizzazione>>
dovrà solo realizzare classi e componenti secondari che implementino il comportamento specificato da un componente
di <<specifica>> separato.
La separazione tra specifica e realizzazione consente essenzialmente due descrizioni separate del sottosistema. La
specifica viene utilizzata come un contratto che definisce tutto ciò che è necessario ad un client per l'utilizzo del
sottosistema. La realizzazione è la progettazione interna dettagliata prevista come guida per l'implementatore. Se si
desidera supportare più realizzazioni, creare sottosistemi di "realizzazione" separati e estrarre una realizzazione da
ogni sottosistema di realizzazione nel sottosistema di specifica.
Se lo stato interno ed il comportamento del sottosistema è relativamente semplice, potrebbe essere sufficiente
specificare il sottosistema dalle interfacce relative esposte, i diagrammi di stato per descrivere il comportamento ed
il testo descrittivo.
Per lo stato interno complesso ed il comportamento, è possibile utilizzare le classi di analisi per specificare il
sottosistema ad un livello elevato di astrazione. Per grandi sistemi di sistemi, è possibile che la specifica di un
sottosistema includa anche i casi d'uso. Consultare Sviluppo su larga scala di sistemi basati su RUP.
Fornire una specifica dettagliata separata dalla realizzazione è la soluzione più utile nelle situazioni seguenti:
-
lo stato interno o il comportamento della realizzazione del sottosistema sono complessi - ed è necessario esprimere
la specifica il più semplicemente possibile per consentirne ai client l'utilizzo effettivo;
-
il sottosistema è un "componente di assemblaggio" riutilizzabile previsto per l'assemblaggio in un numero di
sistemi (consultare Concetto:
Componente);
-
è previsto che gli elementi interni del sottosistema vengano sviluppati da un'organizzazione separata;
-
è necessario creare implementazioni del sottosistema;
-
si prevede che il sottosistema venga sostituito con un'altra versione con modifiche interne significative ma senza
alcun cambiamento del comportamento visibile all'esterno.
Mantenere una specifica esterna è impegnativo, tuttavia - poiché è necessario garantire che la realizzazione del
sottosistema sia compatibile con la specifica. E' necessario che i criteri per stabilire dove e se creare classi di
realizzazione e specifica separate e collaborazioni, vengano definiti in Prodotto di lavoro: Linee guida specifiche del prodotto.
E' necessario che una specifica definisca le dipendenze relative. Si tratta delle interfacce e degli elementi visibili
da altri sottosistemi e da altri pacchetti che è necessario siano disponibili in tutte le realizzazioni compatibili del
sottosistema.
E' possibile che una realizzazione disponga di ulteriori dipendenze, introdotte dal progettista o dall'implementatore.
Ad esempio, nel caso esista un'opportunità di utilizzare un componente di un programma di utilità per semplificare
l'implementazione - ma l'utilizzo di tale componente è un dettaglio che non è necessario esporre ai client. E'
necessario catturare queste ulteriori dipendenze su un diagramma separato come parte della realizzazione.
Una specifica completamente dettagliata definisce tutto ciò che è necessario al client per utilizzare il sottosistema.
Ciò significa perfezionare le interfacce esposte e qualsiasi elemento pubblicamente visibile in modo da essere uno a
uno con il codice. E' necessario che le classi di analisi introdotte per specificare il comportamento del sottosistema,
rimangano come livello di astrazione elevato, poiché è previsto che siano indipendenti da qualsiasi realizzazione dei
sottosistemi.
E' necessario che gli elementi di realizzazione di un sottosistema siano allineati attentamente al codice.
Consultare Tecnica: Mappatura dalla progettazione al codice per ulteriori discussioni su questo
argomento.
Modellazione
E' possibile modellare i sottosistemi di progettazione o come componenti UML 2.0 o come sottosistemi UML 1.5. Queste
costruzioni forniscono capacità di modellazione quasi equivalenti alla modularità, all'incapsulamento ed istanze in
grado di andare in esecuzione al runtime.
Altre considerazioni relative a queste opzioni di modellazione:
-
I sottosistemi UML 1.5 includono esplicitamente le nozioni di "specifica" e "realizzazione" (precedentemente
definite nella sezione intitolata Specifica e
realizzazione sottosistema). I componenti UML 2.0 supportano la nozione di specifica (nel modulo di una o più
interfacce richieste e fornite) e realizzazione (implementazione interna che consiste di una o più classi e
componenti secondari che realizzano il comportamento relativo).
-
I sottosistemi UML 1.5 erano anche pacchetti. I componenti UML 2.0 dispongono delle capacità di creazione
pacchetti, ossia possono essere proprietari ed importare un insieme potenzialmente elevato di elementi di
modellazione.
Tuttavia, tutto sommato, è possibile utilizzare queste annotazioni scambievolmente. Se rappresentare i sottosistemi di
progettazione come sottosistemi UML 1.5 o componenti UML 2.0 è una decisione che è necessario documentare nelle Linee guida specifiche del progetto personalizzate per il progetto.
Se il tool di modellazione visivo supporta i pacchetti UML 1.5 ma non i sottosistemi UML 1.5, è possibile utilizzare un
pacchetto stereotipato come <<sottosistema>> per indicare un sottosistema.
Restrizioni dipendenze del sottosistema
Le stesse restrizioni delle dipendenze e le discussioni menzionate nella sezione intitolata Restrizioni dipendenze del sottosistema vengono applicate anche per i
sottosistemi di progettazione modellati come sottosistemi UML 1.5.
Segue un esempio di dipendenze pacchetto e sottosistema in UML 1.5:
dipendenze pacchetto e sottosistema nel modello di progettazione
Realizzazione e specifica sottosistema
L'UML 1.5 attesta:
Il contenuto di un sottosistema viene diviso in due sottoinsiemi: 1) elementi di specifica ed 2) elementi di
realizzazione. Gli elementi di specifica, insieme alle operazioni ed alle ricezioni del sottosistema, vengono
utilizzati per creare una specifica astratta del comportamento offerto dagli elementi di realizzazione. La raccolta
degli elementi di realizzazione modella l'interno dell'unità comportamentale del sistema fisico.
La separazione tra specifica e realizzazione consente essenzialmente due descrizioni separate del sottosistema. La
specifica viene utilizzata come un contratto che definisce tutto ciò che è necessario ad un client per l'utilizzo del
sottosistema. La realizzazione è la progettazione interna dettagliata prevista come guida per l'implementatore.
Un'opzione per la modellazione di specifiche e realizzazioni, se non direttamente supportata dall'ambiente di
modellazione, inserirà due pacchetti, specifica e realizzazione, all'interno di ciascun sottosistema.
Una motivazione per le specifiche è quella di supportare più realizzazioni. Questa funzione non è supportata
direttamente nell'UML 1.x. Se si desidera supportare più realizzazioni utilizzando i sottosistemi UML 1.5, creare
sottosistemi di "realizzazione" separati ed estrarre una realizzazione da ogni sottosistema di realizzazione nel
sottosistema di specifica.
In sostanza, le stesse considerazioni relative alle specifiche ed alle realizzazioni applicate per UML 2.0, verranno
applicate anche in questo caso (consultare Quando e come utilizzarlo, Dipendenze e Relazione con l'implementazione
per ulteriori spiegazioni).
Ulteriori informazioni
Fare riferimento a Differenze tra UML 1.x e UML 2.0 per ulteriori informazioni.
|