Concetto: Classe strutturata
Una classe strutturata è una classe composta da parti con una notazione esplicita "nidificata" e viene utilizzata per modellare le gerarchie dei contenuti, che sono delle classi composte da "parti".
Relazioni
Elementi correlati
Descrizione principale

Definizione

Secondo l'UML ([UML04]), una classe è un sottotipo di entrambe le classi EncapsulatedClassifier e metaclasse, che portano alla classe la capacità di disporre di una struttura interna e delle porte. Inoltre, dall'UML un componente viene definito come sottotipo della classe. Quindi, in un contesto RUP, quando si parla di classi strutturate si fa riferimento sia a dei componenti che a delle classi.

Parte

Un'istanza di una classe strutturata contiene un oggetto o una serie di oggetti che corrispondono a ciascuna parte. Tali istanze vengono distrutte quando viene distrutta l'istanza classe strutturata che le contiene.

L'esempio riportato di seguito mostra due possibili viste della classe Car:

Nella figura (a), Car mostra un'associazione di composizione con nome ruolo rear alla classe Wheel e l'associazione di composizione con nome ruolo e alla classe Engine. Qualsiasi istanza della classe Engine può essere collegata ad un numero arbitrario di istanze della classe Wheel.

Nella figura (b), viene specificato la stessa cosa. Tuttavia, in aggiunta, nella figura (b) viene specificato che:

  • rear ed e appartengono ad una struttura interna della classe Car. Questo consente la specifica del dettaglio che contiene solo per le istanze delle classi Wheel e Engine nel contesto della classe Car, ma che non contiene per wheel ed engine in generale.

  • nel contesto della classe Car, l'istanza che assume il ruolo e può essere collegata solo a due istanze che assumono il ruolo rear. Inoltre, le istanze che assumono i ruoli e e rear possono essere collegate solo se si tratta di ruoli della stessa istanza della classe Car.

  • In altre parole, ulteriori vincoli riguardano le istanze delle classi Wheel ed Engine, quando assumono i rispettivi ruoli senza un'istanza della classe Car. Tali vincoli no sono veri per le istanze di Wheel e di Engine in generale. Altri wheel ed engine possono essere arbitrariamente collegati come specificato nella figura (a).

Diagramma descritto nel testo di accompagnamento.

Esempio: Parti che assumono i loro ruoli all'interno di una classe strutturata

Connettore

Un connettore è un'istanza di relazione fra due parti di una classe strutturata. Si tratta di un collegamento che consente la comunicazione. I connettori possono essere implementati da normali associazioni o da relazioni transitorie, ad esempio parametri di procedure, variabili, valori globali o altri meccanismi.

I "collegamenti" interni di una classe strutturata vengono specificati con dei connettori di assemblaggio e di delega:

  • In una implementazione di una classe strutturata, i connettori di assemblaggio collegano le porte di parti diverse. Un messaggio inviato sulla porta di una classe strutturata viene ricevuto su una porta collegata di un'altra classe strutturata. Un insieme di parti può essere interconnesso tramite le rispettive porte. Non è necessario che una parte conosca i dettagli delle altre parti, tranne che esistono e soddisfano i vincoli sulle porte collegate. Le comunicazioni fra le classi strutturate vengono modellate dalle rispettive porte.


  • Un connettore di delega collega la porta esterna di una classe strutturata ad una porta di una delle sue parti interne. Un messaggio ricevuto dalla porta esterna viene trasmesso alla porta sulla parte interna; un messaggio inviato dalla porta interna viene passato alla porta esterna e quindi alla classe strutturata ad essa collegata.

Porta

Una porta è una funzione strutturale di una classe strutturata. L'incapsulamento può essere aumentato forzando le comunicazioni dall'esterno della classe strutturata per passare attraverso le porte obbedendo alle interfacce dichiarate che portano ulteriore precisione nella specifica e nell'interconnessione per quella classe strutturata.

Le interfacce richieste e fornite di una porta specificano tutto il necessario per le interazioni mediante quel punto di interazione. Se tutte le interazioni di una classe strutturata con il suo ambiente vengono ottenute mediante le porte, gli interni della classe strutturata sono completamente isolati dall'ambiente. Questo consente ad una classe strutturata di essere utilizzata in qualunque contesto soddisfi i vincoli specificati dalle porte.

Non esistono assunzioni su come viene implementata una porta. Potrebbe essere implementata come un oggetto esplicito o potrebbe essere semplicemente un concetto virtuale che non compare esplicitamente nell'implementazione.

Di seguito sono riportati degli esempi di porte:

Esempio 1

Diagramma descritto nel testo di accompagnamento.

Porta di un Engine utilizzata da un Car ed un Boat

La figura precedente mostra una classe Engine con una porta p e due interfacce:

  • Un'interfaccia predefinita powertrain, che specifica i servizi che l'engine offre su questa porta (ad es., le operazioni e le ricezioni, accessibili alle comunicazioni in arrivo su questa porta).
  • Un'interfaccia richiesta power, che specifica i servizi che il motore si aspetta che l'ambiente fornisca.

Sulla porta p, la classe Engine è completamente incapsulata; può essere specificata senza alcuna conoscenza dell'ambiente in cui il motore verrà incluso. Finché l'ambiente segue i vincoli espressi dalle interfacce fornite e richieste del motore, il motore funzionerà correttamente.

Per spiegarlo, in questo esempio vengono mostrati due tipi d'uso della classe Engine:

  • La classe Car collega la porta p del motore ad una serie di ruote tramite axle.
  • La classe Boat collega la porta p del motore ad un propulsore tramite lo shaft.

Finché l'interazione fra Engine e la parte collegata alla sua porta p segue i vincoli specificati dalle interfacce fornite e richieste, il motore funzionerà come specificato, a prescindere che si tratti di un motore di automobile o di una barca.

Inoltre, anche se Engine disponeva di altre porte dichiarate, come la porta f per Fuel Consumption, le ruote di una macchina e l'elica di una barca avrebbero ancora accesso all'Engine attraverso la porta p. La porta f interesserebbe un contatore di carburante, a prescindere dal tipo di carburante utilizzato e dal tipo di contatore di cui potrebbero disporre le macchine e le barche.

Esempio 2

Questo esempio di porte di basa su Java Logging API ([JAV03]), un pacchetto che fornisce, fra le altre, le seguenti classi ed interfacce delle funzioni principali di registrazione log della piattaforma Java 2:

  • Logger è l'entità principale su cui le applicazioni effettuano la registrazione delle chiamate. Viene utilizzata per registrare i messaggi di uno specifico sistema o componente dell'applicazione
  • Livello fornisce una guida all'importanza ed urgenza di un messaggio di log
  • Filtro fornisce un controllo granulare di ciò che viene registrato, oltre il controllo fornito dai livelli di log
  • Gestore prende i messaggi dal logger e li esporta su destinazioni differenti (memoria, flussi di output, console, file e socket)
  • Formatter fornisce il supporto per la formattazione dei record di log

Queste classi ed interfacce sono implicate in due importanti tipi di collaborazione. Alcune classi ed interfacce vengono utilizzate per scrivere nel log mentre altre vengono usate per gestire il log. La figura in basso mostra due diverse collaborazioni di cui dispongono i client e gli amministratori con il log, create come collaborazioni UML:

  • Collaborazione Scrittura, dove il ruolo LogClient si collega al ruolo LogWriter per poter scrivere nel log.
  • Collaborazione Gestione, dove il ruolo LogAdministrator si collega al ruolo LogController per poter accedere al log e modificare le impostazioni del log.

Diagramma descritto nel testo di accompagnamento.

Diverse collaborazioni che i client e gli amministratori hanno con il log

Una possibile rappresentazione UML 2.0 per modellare i servizi di registrazione log e le relative collaborazioni potrebbe essere l'utilizzo di un componente con delle porte e delle interfacce dichiarate, come mostrato nella figura riportata di seguito:

Diagramma descritto nel testo di accompagnamento.

Pacchetto API di registrazione log Java implementato come componente con le interfacce fornite raggruppate in porte

Nella specifica API di registrazione log Java, alcuni dei servizi di registrazione log sono stati implementati come classi ed altri come interfacce. In questo esempio ogni servizio viene modellato come interfaccia fornita, che potrebbe essere realizzata dalle parti all'interno del componente. I due diversi tipi di funzionalità correlati alle collaborazioni Scrittura e Gestione menzionate prima potrebbero essere rappresentati dalle interfacce raggruppate in modo logico nelle porte. Quindi si avrà:

  • Le interfacce Logger e Livello raggruppate nella porta LogWriter. Queste interfacce vengono utilizzate dai client di log per scrivere sui log.
  • Le interfacce Gestore, Filtro e Formatter raggruppate nella porta LogController. Queste interfacce vengono utilizzate dagli amministratori di log per accedere al log e modificarne le impostazioni.

Questa alternativa di modellazione porta ad una separazione degli ambiti, raggruppando in modo logico le interfacce in porte diverse. Esiste una ulteriore precisazione per la specifica del componente e l'interconnessione che può avere con il mondo esterno.

Modellazione

Durante la progettazione, le classi ed i componenti possono essere scomposti in raccolte di parti collegate che possono essere a loro volta scomposte ulteriormente.

Per visualizzare la scomposizione di una classe strutturata può essere utilizzato un diagramma di struttura composta. Come esempio la figura riportata di seguito mostra un diagramma di struttura composta per il botteghino in un sistema di biglietteria. Questa classe viene scomposta in tre parti:

  • Un'interfaccia di rivendita biglietti
  • Una guida alle prestazioni che richiama le prestazioni in base alla data e ad altri criteri
  • Un insieme di database che contiene i dati delle prestazioni dei biglietti.

Ogni parte interagisce mediante un'interfaccia ben definita specificata dalle relative porte. L'intero botteghino interagisce con l'esterno attraverso una porta. I messaggi su questa porta vengono distribuiti alla classe rivendita di biglietti ma la struttura interna della classe botteghino viene nascosta ai client esterni.

Diagramma descritto nel testo di accompagnamento.

Esempio: Diagramma di struttura composta di un sistema di biglietteria.

Rappresentazione UML 1.x

La classe strutturata è un concetto nuovo in UML 2.0.

Molto di quello che RUP definisce come Capsula può essere rappresentato utilizzando la classe strutturata come notazione (consultare Prodotto di lavoro: Capsula e Linea guida per il prodotto di lavoro: Capsula per ulteriori informazioni su questo argomento).

Se il tool supporta solo UML 1.5, una rappresentazione alternativa viene trattata anche in Prodotto di lavoro: Capsula e in Guida del prodotto di lavoro: Capsula.

Per ulteriori informazioni consultare Differenze fra UML 1.x e UML 2.0.