Linea guida: Classe di analisi
Esistono tre stereotipi di classi di analisi: boundary, controllo ed entità. Questa linea guida ne spiega il significato e l'utilizzo.
Relazioni
Descrizione principale

Stereotipi delle classi di analisi

Le classi di analisi possono essere stereotipate in una delle seguenti:

  • Classi di boundary
  • Classi di controllo
  • Classi di entità

Oltre a fornire una guida specifica del processo durante la rilevazione di classi, questa stereotipizzazione dà come risultato un modello di oggetto solido perché le modifiche al modello tendono a influenzare solo una specifica area. Ad esempio, le modifiche nell'interfaccia utente influenzeranno solo le classi di boundary. Le modifiche nel flusso di controllo influenzeranno solo le classi di controllo. Le modifiche nelle informazioni a lungo termine inciderà solo sulle classi di entità. Tuttavia, tali stereotipi sono utili specialmente come supporto per identificare le classi nell'analisi e nella progettazione iniziale. Sarebbe opportuno considerare l'utilizzo di una serie di stereotipi leggermente differente nelle fasi successive della progettazione da correlare meglio all'ambiente di implementazione, al tipo di applicazione e così via.

Classe di boundary icona della classe di boundary

Una classe di boundary viene utilizzata per modellare l'interazione fra gli ambienti del sistema e le relative operazioni interne. Tale interazione implica la trasformazione e la conversione degli eventi e l'individuazione delle modifiche nella presentazione del sistema (ad esempio nell'interfaccia).

Le classi boundary modellano le parti del sistema che dipendono dai relativi elementi associati. Le classi di entità e le classi di controllo modellano le parti indipendenti dagli elementi associati al sistema. Quindi, modificando la GUI o il protocollo di comunicazione, vengono cambiate solo le classi di boundary, non quelle di entità e di controllo.

La classi boundary rendono più semplici la comprensione del sistema perché chiarificano i boundary del sistema. Esse favoriscono la progettazione fornendo un buon punto di partenza per l'identificazione dei servizi correlati. Ad esempio, se si identifica l'interfaccia di una stampante all'inizio della progettazione, si noterà subito che occorre anche modellare la formattazione delle stampe.

Le classi di boundary comuni includono finestre, protocolli di comunicazione, interfacce di stampe, sensori e terminali. Non è necessario modellare le parti di routine dell'interfaccia, ad esempio i pulsanti, come classi di boundary separate. Generalmente, l'intera finestra è l'oggetto di boundary definito in modo più dettagliato. Le classi di boundary sono utili anche per la cattura di interfacce in API non OO (object-oriented), come ad esempio il codice legacy.

Si consiglia di modellare le classi di boundary in base al tipo di boundary che rappresentano. La comunicazione con un altro sistema e la comunicazione con un attore umano (tramite un'interfaccia utente) hanno obiettivi molto diversi. Per la comunicazione con un attore umano, il problema più importante è in che modo l'interfaccia verrà presentata all'utente. Per la comunicazione con un altro sistema, il problema più importante è il protocollo di comunicazione.

Un oggetto di boundary (un'istanza di una classe boundary) può resistere a un'istanza del caso d'uso se, ad esempio, deve comparire in una schermata tra le prestazioni dei due casi d'uso. Normalmente, tuttavia, gli oggetti di boundary rimangono attivi per tutto il tempo dell'istanza del caso d'uso.

Rilevazione delle classi boundary

Una classe boundary è l'intermediario tra l'interfaccia e un elemento al di fuori del sistema. Gli oggetti di boundary isolano il sistema dalle modifiche negli elementi associati (modifiche nelle interfacce in altri sistemi, modifiche nei requisiti dell'utente, ecc.), impedendo che tali modifiche influiscano sul resto del sistema.

Un sistema può avere diversi tipi di classi boundary:

  • Classi di interfacce utente - classi che mediano la comunicazione con gli utenti del sistema
  • Classi di interfacce del sistema - classi che mediano la comunicazione con altri sistemi
  • Classi di interfacce dell'unità - classi che forniscono l'interfaccia alle unità (ad esempio i sensori), che rilevano gli eventi esterni
Rilevazione delle classi di interfacce utente

Definire una classe boundary per ogni coppia di attori del caso d'uso. E' possibile visualizzare questa classe come se fosse responsabile della coordinazione dell'interazione con l'attore. E' anche possibile definire le classi boundary aggiuntive per rappresentare le classi sussidiarie a cui la classe boundary primaria delega alcune delle proprie responsabilità. Ciò vale in modo particolare per le applicazioni GUI basate sulla finestra, in cui è possibile modellare un oggetto di boundary per ogni finestra o per ogni modulo. Modellare solo le astrazioni chiave del sistema; non modellare ogni pulsante, elenco e widget nella GUI. L'obiettivo dell'analisi è creare una buona immagine di come è composto il sistema, non per progettare ogni minimo dettaglio. In altre parole, identificare le classi boundary solo per fenomeni nel sistema o per elementi menzionati nel flusso di eventi della realizzazione del caso d'uso di analisi.

Creare bozze o utilizzare dump dello schermo da un Prototipo dell'interfaccia utente, che illustra la funzionalità e l'aspetto delle classi boundary.

Rilevazione delle classi di interfacce del sistema

Una classe boundary che comunica con un sistema esterno è responsabile per la gestione della comunicazione con il sistema esterno; essa fornisce l'interfaccia per il sistema che si sta costruendo.

Esempio

In uno sportello automatico, il prelievo di fondi deve essere verificato tramite la relativa rete, un attore (che, a turno, verifica il prelievo con il sistema di contabilità in banca). Un oggetto, denominato Interfaccia della rete dello sportello automatico, può essere identificato per fornire la comunicazione con la suddetta rete.

E' possibile che l'interfaccia a un sistema esistente sia già ben definita; in tal caso, le responsabilità dovrebbero essere derivate direttamente dalla definizione dell'interfaccia. Se esiste una definizione dell'interfaccia formale, è possibile eseguire il reverse engineering su di essa e non è necessario definirla formalmente; tenere presente solo che l'interfaccia esistente verrà riutilizzata durante la progettazione.

Rilevazione delle classi dell'interfaccia dell'unità

Il sistema potrebbe contenere elementi che si comportano come se fossero esterni (modificano spontaneamente il valore senza alcun oggetto nel sistema che li influenzi), ad esempio un sensore. Sebbene sia possibile rappresentare tale tipo di unità esterna utilizzando gli attori, gli utenti del sistema potrebbero trovare tale operazione "confusionaria", perché tende a collocare unità e attori umani sullo stesso "livello". Una volta che ci si allontana dai requisiti di raccolta, tuttavia, è necessario considerare l'origine di tutti gli eventi esterni e accertarsi che il sistema disponga di un modo per rilevare tali eventi.

Se l'unità è rappresentata come attore nel modello del caso d'uso, è semplice trovare una giustificazione utilizzando una classe boundary per mediare la comunicazione tra l'unità e il sistema. Se il modello del caso d'uso non include tali "attori-unità", ora è il momento giusto per aggiungerli, aggiornando le descrizioni supplementari dei casi d'uso, dove sono necessarie.

Per ogni "attore-unità", creare una classe boundary per catturare le responsabilità dell'unità o del sensore. Se esiste già un'interfaccia ben definita per l'unità, prenderne nota per un successivo riferimento durante la progettazione.

Classe di controllo icona della classe di controllo

Una classe di controllo viene utilizzata per modellare la funzionalità del controllo specifica per uno o più casi d'uso. Gli oggetti di controllo (istanze delle classi di controllo) spesso controllano altri oggetti, quindi la relativa funzionalità è di tipo coordinante. Le classi di controllo incapsulano la funzionalità specifica del caso d'uso.

La funzionalità specifica di un oggetto di controllo è strettamente correlata alla realizzazione di un determinato caso d'uso. In molti scenari, è possibile affermare anche che gli oggetti di controllo "eseguono" le realizzazioni dei casi d'uso d'analisi. Tuttavia, alcuni oggetti di controllo possono partecipare a più realizzazioni dei casi d'uso d'analisi se le attività di tali casi d'uso sono strettamente correlate. Inoltre, diversi oggetti di controllo di differenti classi di controllo possono partecipare a più casi d'uso. Non tutti i casi d'uso richiedono un oggetto di controllo. Ad esempio, se il flusso di eventi in un caso d'uso è correlato a un oggetto di entità, un oggetto di boundary può realizzare il caso d'uso in cooperazione con l'oggetto di entità. E' possibile iniziare identificando una classe di controllo per realizzazione del caso d'uso d'analisi e quindi perfezionarla man mano che vengono identificate ulteriori realizzazioni e che viene individuata una comunalità.

Le classi di controllo possono contribuire alla comprensione del sistema perché rappresentano la dinamica del sistema, gestendo le attività e i flussi di controllo principali.

Quando il sistema esegue il caso d'uso, viene creato un oggetto di controllo. Tali oggetti, generalmente, cessano di esistere una volta eseguito il corrispondente caso d'uso.

Tenere presente che una classe di controllo non gestisce ogni elemento necessario in un caso d'uso. Essa coordina, invece, le attività di altri oggetti che implementano la funzionalità. La classe di controllo delega il valore agli oggetti a cui è stata assegnata la responsabilità per la funzionalità.

Rilevazione delle classi di controllo

Le classi di controllo forniscono la funzionalità di coordinazione nel sistema. Il sistema può eseguire alcuni casi d'uso senza gli oggetti di controllo (utilizzando soltanto gli oggetti di entità e di boundary), in particolare i casi d'uso che includono solo la semplice gestione delle informazioni memorizzate.

I casi d'uso più complessi generalmente richiedono una o più classi di controllo per coordinare la funzionalità di altri oggetti nel sistema. Gli esempi di oggetti di controllo includono programmi come i responsabili di transazione, i coordinatori di risorse e i gestori di errori.

Le classi di controllo separano gli oggetti di boundary e di entità l'uno dall'altro, rendendo il sistema più tollerante alle modifiche nel boundary del sistema. Essi separano anche la funzionalità specifica del caso d'uso dagli oggetti di entità, rendendoli più riutilizzabili attraverso i sistemi e i casi d'uso.

Le classi di controllo forniscono una funzionalità che:

  • è indipendente dagli elementi circostanti (non cambia quando cambiano gli elementi circostanti),
  • definisce la logica di controllo (ordine tra eventi) e le transazioni all'interno di un caso d'uso.
  • cambia lievemente se la struttura o la funzionalità interna delle classi di entità viene modificata,
  • utilizza o imposta il contenuto di diverse classi di entità e, quindi, necessita la coordinazione della funzionalità di tali classi di entità.
  • non viene eseguita nello stesso modo ogni volta che viene attivata (il flusso di eventi caratterizza diversi stati).
Come stabilire se una classe di controllo è necessaria

Il flusso di eventi di un caso d'uso definisce l'ordine in cui vengono eseguite le differenti attività. Iniziare cercando di capire se il flusso può essere gestito dalle classi di entità e di boundary già identificate. Per flussi di eventi semplici che, principalmente, richiamano e visualizzano o modificano le informazioni, una classe di controllo non viene, generalmente, giustificata; le classi boundary saranno responsabili per il coordinamento del caso d'uso.

Si consiglia di incapsulare i flussi di eventi in una classe di controllo separata quando è complessa e consiste in una funzionalità dinamica che può cambiare in modo indipendente dalle interfacce (classi boundary) o dalle memorizzazioni di informazioni (classi di entità) del sistema. Incapsulando i flussi di eventi, è possibile riutilizzare la classe di controllo per vari sistemi con interfacce e memorizzazioni dati differenti (o almeno le strutture di dati sottostanti).

Esempio: gestione di una coda di attività

E' possibile identificare una classe di controllo dal caso d'uso caso d'uso Esecuzione attività nel sistema di gestione magazzino. Tale classe di controllo gestisce una coda di attività, verificando che le attività vengano eseguite nell'ordine corretto. Essa esegue la successiva attività nella coda non appena viene assegnata l'attrezzatura di trasporto appropriata. Il sistema può, quindi, eseguire diverse attività contemporaneamente.

La funzionalità definita dall'oggetto di controllo corrispondente è più semplice da descrivere se la si suddivide in due classi di controllo: Esecutore compito e Gestore coda. Un oggetto Gestore coda gestirà solo l'ordine della coda e l'assegnazione dell'attrezzatura di trasporto. Un oggetto Gestore coda è necessario per l'intera coda. Non appena il sistema esegue un'attività, esso crea un nuovo oggetto Esecutore compito, che eseguirà l'attività. E' quindi necessario un oggetto Esecutore compito per ogni attività eseguita dal sistema.

le classi "troppo complesse" dovrebbero essere suddivise in classi con una serie coerente e correlata di responsabilità

Si consiglia di suddividere le classi complesse dovrebbero lungo linee di responsabilità simili.

Il vantaggio principale di questa suddivisione è che sono state separate le responsabilità di gestione coda (elementi generici per diversi casi d'uso) dalle particolari attività di gestione attività, specifiche per questo caso d'uso. Ciò rende più semplice la comprensione e l'adattamento delle classi al progredire della progettazione. Vi sono, inoltre, dei vantaggi nel bilanciamento del carico del sistema, poiché è possibile creare tutti gli Esecutori compito necessari per gestire il carico di lavoro.

Incapsulamento del flusso di eventi principale e dei flussi di eventi alternativi/eccezionali in classi di controllo separate

Per semplificare le modifiche, incapsulare il flusso di eventi principale e i flussi di eventi alternativi in classi di controllo differenti. Se i flussi alternativi ed eccezionali sono completamente indipendenti, separarli. In questo modo, sarà più semplice l'estensione e la gestione del sistema nel tempo.

Divisione delle classi di controllo in cui due attori condividono la stessa classe

Potrebbe anche essere necessario dividere le classi di controllo quando diversi attori utilizzano la stessa classe. In tal modo, le modifiche vengono isolate dal resto del sistema, nei requisiti di un attore. Nei casi in cui il costo della modifica è elevato o le conseguenze estreme, si consiglia di identificare tutte le classi di controllo relative a uno o più attori e dividerle. Nel caso ideale, ogni classe di controllo dovrebbe interagire (tramite un oggetto di boundary) con un attore o con nessuno.

Esempio: gestione di una chiamata

Considerare il caso d'uso Chiamata locale. Inizialmente, è possibile identificare una classe di controllo per gestire la chiamata stessa.

I differenti attori coinvolti in un caso d'uso generalmente richiedono classi di controllo separate

La classe di controllo che gestisce le chiamate del telefono locali in un sistema telefonico possono essere divise, rapidamente, in due classi di controllo, funzionalità-A e funzionalità-B, una per ogni attore coinvolto.

In una chiamata telefonica locale, sono presenti due attori: abbonato telefonico-A che avvia la chiamata e abbonato telefonico-B che riceve la chiamata. L'abbonato telefonico-A solleva il ricevitore, sente il segnale di libero e quindi digita un numero, che il sistema memorizza e analizza. Quando il sistema ha ricevuto tutte le cifre, invia un segnale di libero all'abbonato telefonico-A e uno squillo all'abbonato telefonico-B. Quando l'abbonato telefonico-B risponde, il tono e il segnale vengono interrotti e la conversazione tra gli abbonati può iniziare. La chiamata viene terminata quando entrambi gli abbonati attaccano.

E' necessario controllare due funzionalità: cosa succede a casa dell'abbonato A e cosa succede a casa dell'abbonato B. Per questo motivo, l'oggetto di controllo originale è stato suddiviso in due oggetti di controllo, Funzionalità-A e Funzionalità-B.

Non è necessario suddividere una classe di controllo se:

  • Si può avere la certezza che il comportamento degli attori correlati agli oggetti della classe di controllo non verrà mai modificato o cambierà di poco.
  • La funzionalità di un oggetto della classe di controllo verso un attore è piuttosto insignificante rispetto a quella di un altro attore, un singolo oggetto può contenere l'intera funzionalità. La combinazione delle funzionalità in questo modo avrà un effetto trascurabile sulla capacità di cambiamento.

Classe di entità icona della classe di entità

Una classe di entità viene utilizzata per modellare le informazioni e la funzionalità associata che occorre memorizzare. Gli oggetti di entità (istanze di classi di entità) vengono utilizzati per conservare e aggiornare le informazioni sullo stesso fenomeno, ad esempio un evento, una persona o un oggetto della vita reale. Essi sono, di solito, permanenti, dispongono di attributi e relazioni necessari per un lungo periodo, talvolta per l'intera durata del sistema.

Un oggetto di entità, generalmente, non è specifico per una realizzazione del caso d'uso; a volte, un oggetto di entità non è neanche specifico per il sistema stesso. I valori dei relativi attributi e relazioni vengono spesso forniti da un attore. Un oggetto di entità può anche essere necessario per favorire l'esecuzione delle attività di sistema interne. Gli oggetti di entità possono avere funzionalità complicate come quelle degli altri stereotipi di oggetti. Tuttavia, a differenza di altri oggetti, questa funzionalità è strettamente correlata al fenomeno che l'oggetto di entità rappresenta. Gli oggetti di entità sono indipendenti dall'ambiente (gli attori).

Gli oggetti di entità rappresentano i concetti chiave del sistema che si sta sviluppando. Esempi tipici di classi di entità in un sistema bancario sono Conto e Cliente. In un sistema di gestione rete, gli esempi sono Nodo e Collegamento.

Se il fenomeno che si desidera modellare non è utilizzato da un'altra classe, è possibile modellarlo come attributo di una classe di entità o anche come relazione tra classi di entità. Dall'altra parte, se il fenomeno viene utilizzato da un'altra classe nel modello di progettazione, occorre modellarlo come classe.

Le classi di entità forniscono un altro punto di vista da cui comprendere il sistema, perché mostrano la struttura logica dei dati, che consente di individuare le possibili offerte del sistema ai propri utenti.

Rilevazione delle classi di entità

Le classi di entità rappresentano memorizzazioni di informazioni nel sistema; esse vengono generalmente utilizzate per rappresentare i concetti chiave gestiti dal sistema. Gli oggetti di entità sono, spesso, passivi e permanenti. Le loro responsabilità principali sono la memorizzazione e la gestione delle informazioni nel sistema.

Una fonte di ispirazione frequente per le classi di entità sono il Glossario (sviluppato durante i requisiti) e un modello di dominio business (sviluppato durante la modellazione business, se tale modellazione è stata eseguita).

Limitazioni all'utilizzo dello stereotipo di associazione

Limitazioni per le classi di boundary

E' consentito quanto segue:

  • Comunicazione delle associazioni tra due classi boundary, ad esempio, per descrivere in che modo una specifica finestra è correlata ad altri oggetti boundary.
  • Comunicazione o sottoscrizione da una classe boundary a una classe di entità, perché gli oggetti boundary potrebbero dover tenere traccia di determinati oggetti di entità tra azioni nell'oggetto boundary o essere informati delle modifiche di stato nell'oggetto di entità.
  • Comunicazione di associazioni da una classe boundary a una classe di controllo, in modo che un oggetto boundary possa attivare una determinata funzionalità.

Limitazioni per le classi di controllo

E' consentito quanto segue:

  • Comunicazione o sottoscrizione tra classi di controllo e classi di entità, perché gli oggetti di controllo potrebbero dover tenere traccia di determinati oggetti di entità tra azioni nell'oggetto di controllo o essere informati delle modifiche di stato nell'oggetto di entità.
  • Comunicazione di associazioni tra le classi di controllo e boundary, consentendo la comunicazione dei risultati della funzionalità richiamata all'ambiente.
  • Comunicazione di associazioni tra classi di controllo, consentendo la costruzione di modelli di funzionalità più complessi.

Limitazioni per le classi di entità

La classi di entità dovrebbero essere soltanto la fonte di associazioni (comunicazione o sottoscrizione) ad altre classi di entità. Gli oggetti della classe di entità dovrebbero essere di lunga durata, a differenza degli oggetti della classe di controllo e di boundary. Da un punto di vista strutturale, è bene limitare la visibilità che un oggetto di entità ha dei relativi elementi associati; in tal modo, il sistema è più suscettibile alle modifiche.

Riepilogo delle limitazioni

FromTo
(navigabilità)

Boundary

Entità

Controllo

Boundary

comunicazione

comunicazione

sottoscrizione

comunicazione

Entità

comunicazione

sottoscrizione

 

Controllo

comunicazione

comunicazione

sottoscrizione

comunicazione

Combinazioni di stereotipi di associazioni valide

Rafforzamento della coerenza

  • Quando viene identificata una nuova funzionalità, verificare che sia presente una classe esistente con responsabilità simili, riutilizzando le classi dove possibile. Solo quando si è certi che non vi è alcun oggetto esistente che può eseguire la funzionalità, si consiglia di creare nuove classi.
  • Non appena le classi vengono identificate, esaminarle per verificare che abbiano responsabilità coerenti. Quando le responsabilità delle classi sono sconnesse, suddividere l'oggetto in due o più classi. Aggiornare i diagrammi di interazione, di conseguenza.
  • Se una classe viene suddivisa perché vengono rilevate responsabilità sconnesse, esaminare le collaborazioni in cui la classe ha un ruolo, per controllare se è necessario aggiornare la collaborazione. Aggiornare la collaborazione, se necessario.
  • Una classe con una sola responsabilità non è un problema di per se, ma dovrebbe generare domande solo se necessario. Essere preparati alla sfida e a giustificare l'esistenza di tutte le classi.