OOAD - Design orientato agli oggetti
Dopo la fase di analisi, il modello concettuale viene ulteriormente sviluppato in un modello orientato agli oggetti utilizzando la progettazione orientata agli oggetti (OOD). In OOD, i concetti indipendenti dalla tecnologia nel modello di analisi vengono mappati su classi di implementazione, vengono identificati i vincoli e vengono progettate le interfacce, ottenendo un modello per il dominio della soluzione. In poche parole, viene costruita una descrizione dettagliata che specifica come il sistema deve essere costruito su tecnologie concrete
Le fasi per la progettazione orientata agli oggetti possono essere identificate come:
- Definizione del contesto del sistema
- Progettazione dell'architettura del sistema
- Identificazione degli oggetti nel sistema
- Costruzione di modelli di design
- Specifica delle interfacce degli oggetti
Sistema di design
La progettazione di un sistema orientata agli oggetti implica la definizione del contesto di un sistema seguita dalla progettazione dell'architettura del sistema.
Context- Il contesto di un sistema ha una parte statica e una dinamica. Il contesto statico del sistema è progettato utilizzando un semplice diagramma a blocchi dell'intero sistema che viene espanso in una gerarchia di sottosistemi. Il modello del sottosistema è rappresentato dai pacchetti UML. Il contesto dinamico descrive come il sistema interagisce con il suo ambiente. È modellato utilizzandouse case diagrams.
System Architecture- L'architettura del sistema è progettata sulla base del contesto del sistema in conformità con i principi della progettazione architettonica e della conoscenza del dominio. Tipicamente, un sistema è suddiviso in strati e ogni strato viene scomposto per formare i sottosistemi.
Decomposizione orientata agli oggetti
Decomposizione significa dividere un grande sistema complesso in una gerarchia di componenti più piccoli con complessità minori, sui principi del divide et impera. Ogni componente principale del sistema è chiamato sottosistema. La scomposizione orientata agli oggetti identifica i singoli oggetti autonomi in un sistema e la comunicazione tra questi oggetti.
I vantaggi della decomposizione sono:
I singoli componenti sono di minore complessità e quindi più comprensibili e gestibili.
Consente la divisione della forza lavoro con competenze specialistiche.
Consente di sostituire o modificare i sottosistemi senza influire su altri sottosistemi.
Identificazione della concorrenza
La concorrenza consente a più di un oggetto di ricevere eventi contemporaneamente e di eseguire più di un'attività contemporaneamente. La concorrenza viene identificata e rappresentata nel modello dinamico.
Per abilitare la concorrenza, a ogni elemento simultaneo viene assegnato un thread di controllo separato. Se la concorrenza è a livello di oggetto, a due oggetti simultanei vengono assegnati due diversi thread di controllo. Se due operazioni di un singolo oggetto sono di natura simultanea, quell'oggetto viene suddiviso in diversi thread.
La concorrenza è associata ai problemi di integrità dei dati, deadlock e fame. Quindi è necessario definire una strategia chiara ogni volta che è richiesta la concorrenza. Inoltre, la concorrenza deve essere identificata nella fase di progettazione stessa e non può essere lasciata alla fase di implementazione.
Identificazione dei modelli
Durante la progettazione delle applicazioni, per alcune categorie di problemi vengono adottate alcune soluzioni comunemente accettate. Questi sono i modelli di design. Un modello può essere definito come un insieme documentato di elementi costitutivi che possono essere utilizzati in determinati tipi di problemi di sviluppo dell'applicazione.
Alcuni modelli di design comunemente usati sono:
- Modello di facciata
- Schema di separazione della vista del modello
- Modello osservatore
- Modello controller vista modello
- Pubblica modello di iscrizione
- Modello proxy
Controllo degli eventi
Durante la progettazione del sistema, gli eventi che possono verificarsi negli oggetti del sistema devono essere identificati e adeguatamente gestiti.
Un evento è una specifica di un evento significativo che ha una posizione nel tempo e nello spazio.
Esistono quattro tipi di eventi che possono essere modellati, vale a dire:
Signal Event - Un oggetto con nome lanciato da un oggetto e catturato da un altro oggetto.
Call Event - Un evento sincrono che rappresenta l'invio di un'operazione.
Time Event - Un evento che rappresenta il passare del tempo.
Change Event - Un evento che rappresenta il cambiamento di stato.
Gestione delle condizioni al contorno
La fase di progettazione del sistema deve affrontare l'inizializzazione e la terminazione del sistema nel suo insieme e di ogni sottosistema. I diversi aspetti documentati sono i seguenti:
L'avvio del sistema, ovvero la transizione del sistema dallo stato non inizializzato allo stato stazionario.
La terminazione del sistema, cioè la chiusura di tutti i thread in esecuzione, la pulizia delle risorse e i messaggi da inviare.
La configurazione iniziale del sistema e la riconfigurazione del sistema quando necessario.
Prevedere guasti o interruzioni indesiderate del sistema.
Le condizioni al contorno sono modellate utilizzando casi d'uso limite.
Object Design
Dopo che la gerarchia dei sottosistemi è stata sviluppata, gli oggetti nel sistema vengono identificati e i loro dettagli vengono progettati. Qui, il progettista descrive in dettaglio la strategia scelta durante la progettazione del sistema. L'enfasi si sposta dai concetti del dominio dell'applicazione verso i concetti del computer. Gli oggetti identificati durante l'analisi vengono incisi per l'implementazione con l'obiettivo di ridurre al minimo il tempo di esecuzione, il consumo di memoria e il costo complessivo.
La progettazione degli oggetti comprende le seguenti fasi:
- Identificazione di oggetti
- Rappresentazione di oggetti, ovvero costruzione di modelli di progetto
- Classificazione delle operazioni
- Progettazione di algoritmi
- Progettazione delle relazioni
- Implementazione del controllo per le interazioni esterne
- Pacchetti di classi e associazioni in moduli
Identificazione degli oggetti
Il primo passo della progettazione di oggetti è l'identificazione degli oggetti. Gli oggetti identificati nelle fasi di analisi orientata agli oggetti sono raggruppati in classi e raffinati in modo che siano adatti per l'effettiva implementazione.
Le funzioni di questa fase sono:
Identificazione e perfezionamento delle classi in ogni sottosistema o pacchetto
Definizione dei collegamenti e delle associazioni tra le classi
Progettare le associazioni gerarchiche tra le classi, cioè la generalizzazione / specializzazione e le eredità
Progettare aggregazioni
Rappresentazione dell'oggetto
Una volta identificate le classi, è necessario rappresentarle utilizzando tecniche di modellazione a oggetti. Questa fase implica essenzialmente la costruzione di diagrammi UML.
Ci sono due tipi di modelli di design che devono essere prodotti:
Static Models - Descrivere la struttura statica di un sistema utilizzando diagrammi di classe e diagrammi di oggetti.
Dynamic Models - Descrivere la struttura dinamica di un sistema e mostrare l'interazione tra classi utilizzando diagrammi di interazione e diagrammi di stato-grafico.
Classificazione delle operazioni
In questa fase, le operazioni da eseguire sugli oggetti vengono definite combinando i tre modelli sviluppati nella fase OOA, ovvero modello a oggetti, modello dinamico e modello funzionale. Un'operazione specifica cosa deve essere fatto e non come dovrebbe essere fatto.
Le seguenti attività vengono eseguite per quanto riguarda le operazioni:
Viene sviluppato il diagramma di transizione di stato di ogni oggetto nel sistema.
Le operazioni sono definite per gli eventi ricevuti dagli oggetti.
Vengono identificati i casi in cui un evento attiva altri eventi in oggetti uguali o diversi.
Vengono identificate le sotto-operazioni all'interno delle azioni.
Le azioni principali sono estese ai diagrammi di flusso di dati.
Progettazione di algoritmi
Le operazioni negli oggetti vengono definite utilizzando algoritmi. Un algoritmo è una procedura graduale che risolve il problema posto in un'operazione. Gli algoritmi si concentrano su come deve essere fatto.
Potrebbe esserci più di un algoritmo corrispondente a una determinata operazione. Una volta identificati gli algoritmi alternativi, viene selezionato l'algoritmo ottimale per il dominio del problema dato. Le metriche per la scelta dell'algoritmo ottimale sono:
Computational Complexity - La complessità determina l'efficienza di un algoritmo in termini di tempo di calcolo e requisiti di memoria.
Flexibility - La flessibilità determina se l'algoritmo scelto può essere implementato adeguatamente, senza perdita di adeguatezza nei vari ambienti.
Understandability - Questo determina se l'algoritmo scelto è facile da capire e implementare.
Progettazione delle relazioni
La strategia per implementare le relazioni deve essere definita durante la fase di progettazione degli oggetti. Le relazioni principali che vengono affrontate comprendono associazioni, aggregazioni ed eredità.
Il progettista dovrebbe fare quanto segue riguardo alle associazioni:
Identifica se un'associazione è unidirezionale o bidirezionale.
Analizza il percorso delle associazioni e aggiornale se necessario.
Implementare le associazioni come un oggetto distinto, in caso di relazioni molti-a-molti; o come collegamento ad un altro oggetto in caso di relazioni uno-a-uno o uno-a-molti.
Per quanto riguarda le eredità, il progettista dovrebbe fare quanto segue:
Modifica le classi e le loro associazioni.
Identifica le classi astratte.
Prendi provvedimenti in modo che i comportamenti siano condivisi quando necessario.
Attuazione del controllo
Il progettista di oggetti può incorporare perfezionamenti nella strategia del modello del diagramma di stato. Nella progettazione del sistema, viene creata una strategia di base per la realizzazione del modello dinamico. Durante la progettazione degli oggetti, questa strategia è opportunamente abbellita per un'adeguata implementazione.
Gli approcci per l'implementazione del modello dinamico sono:
Represent State as a Location within a Program- Questo è il tradizionale approccio basato sulla procedura in base al quale la posizione di controllo definisce lo stato del programma. Una macchina a stati finiti può essere implementata come programma. Una transizione forma un'istruzione di input, il percorso di controllo principale forma la sequenza di istruzioni, i rami formano le condizioni ei percorsi all'indietro formano i loop o le iterazioni.
State Machine Engine- Questo approccio rappresenta direttamente una macchina a stati attraverso una classe motore di macchina a stati. Questa classe esegue la macchina a stati attraverso una serie di transizioni e azioni fornite dall'applicazione.
Control as Concurrent Tasks- In questo approccio, un oggetto viene implementato come attività nel linguaggio di programmazione o nel sistema operativo. Qui, un evento viene implementato come una chiamata tra le attività. Conserva la concorrenza intrinseca di oggetti reali.
Classi di imballaggio
In qualsiasi progetto di grandi dimensioni, è importante il partizionamento meticoloso di un'implementazione in moduli o pacchetti. Durante la progettazione degli oggetti, le classi e gli oggetti vengono raggruppati in pacchetti per consentire a più gruppi di lavorare in modo cooperativo su un progetto.
I diversi aspetti del packaging sono:
Hiding Internal Information from Outside View - Consente di visualizzare una classe come una "scatola nera" e consente di modificare l'implementazione della classe senza richiedere ai client della classe di modificare il codice.
Coherence of Elements - Un elemento, come una classe, un'operazione o un modulo, è coerente se è organizzato su un piano coerente e tutte le sue parti sono intrinsecamente correlate in modo da servire un obiettivo comune.
Construction of Physical Modules - Le seguenti linee guida aiutano durante la costruzione dei moduli fisici -
Le classi in un modulo dovrebbero rappresentare cose o componenti simili nello stesso oggetto composito.
Le classi strettamente connesse dovrebbero essere nello stesso modulo.
Le classi non connesse o debolmente connesse dovrebbero essere collocate in moduli separati.
I moduli dovrebbero avere una buona coesione, ovvero un'elevata cooperazione tra i suoi componenti.
Un modulo dovrebbe avere un basso accoppiamento con altri moduli, cioè l'interazione o l'interdipendenza tra i moduli dovrebbe essere minima.
Ottimizzazione del design
Il modello di analisi acquisisce le informazioni logiche sul sistema, mentre il modello di progettazione aggiunge dettagli per supportare un accesso efficiente alle informazioni. Prima che un progetto venga implementato, dovrebbe essere ottimizzato in modo da rendere l'implementazione più efficiente. Lo scopo dell'ottimizzazione è ridurre al minimo il costo in termini di tempo, spazio e altre metriche.
Tuttavia, l'ottimizzazione del progetto non dovrebbe essere eccessiva, poiché anche la facilità di implementazione, la manutenibilità e l'estensibilità sono questioni importanti. Si è spesso visto che un design perfettamente ottimizzato è più efficiente ma meno leggibile e riutilizzabile. Quindi il designer deve trovare un equilibrio tra i due.
Le varie cose che possono essere fatte per l'ottimizzazione del progetto sono:
- Aggiungi associazioni ridondanti
- Ometti associazioni non utilizzabili
- Ottimizzazione degli algoritmi
- Salva gli attributi derivati per evitare il ricalcolo di espressioni complesse
Aggiunta di associazioni ridondanti
Durante l'ottimizzazione del progetto, viene verificato se derivare nuove associazioni può ridurre i costi di accesso. Sebbene queste associazioni ridondanti possano non aggiungere alcuna informazione, possono aumentare l'efficienza del modello complessivo.
Omissione di associazioni non utilizzabili
La presenza di troppe associazioni può rendere un sistema indecifrabile e quindi ridurre l'efficienza complessiva del sistema. Pertanto, durante l'ottimizzazione, tutte le associazioni non utilizzabili vengono rimosse.
Ottimizzazione degli algoritmi
Nei sistemi orientati agli oggetti, l'ottimizzazione della struttura dei dati e degli algoritmi viene eseguita in modo collaborativo. Una volta che il design della classe è in atto, le operazioni e gli algoritmi devono essere ottimizzati.
L'ottimizzazione degli algoritmi si ottiene:
- Riorganizzazione dell'ordine dei compiti computazionali
- Inversione dell'ordine di esecuzione dei loop rispetto a quello previsto nel modello funzionale
- Rimozione dei percorsi morti all'interno dell'algoritmo
Salvataggio e archiviazione di attributi derivati
Gli attributi derivati sono quegli attributi i cui valori sono calcolati in funzione di altri attributi (attributi di base). Il ricalcolo dei valori degli attributi derivati ogni volta che sono necessari è una procedura che richiede tempo. Per evitare ciò, i valori possono essere calcolati e archiviati nelle loro forme calcolate.
Tuttavia, ciò può comportare anomalie di aggiornamento, ovvero un cambiamento nei valori degli attributi di base senza alcuna variazione corrispondente nei valori degli attributi derivati. Per evitare ciò, vengono eseguiti i seguenti passaggi:
Con ogni aggiornamento del valore dell'attributo di base, viene ricalcolato anche l'attributo derivato.
Tutti gli attributi derivati vengono ricalcolati e aggiornati periodicamente in un gruppo anziché dopo ogni aggiornamento.
Documentazione di progettazione
La documentazione è una parte essenziale di qualsiasi processo di sviluppo del software che registra la procedura di creazione del software. Le decisioni di progettazione devono essere documentate per qualsiasi sistema software non banale per la trasmissione del progetto ad altri.
Aree di utilizzo
Sebbene sia un prodotto secondario, una buona documentazione è indispensabile, in particolare nelle seguenti aree:
- Nella progettazione di software sviluppato da numerosi sviluppatori
- In strategie di sviluppo software iterativo
- Nello sviluppo di versioni successive di un progetto software
- Per valutare un software
- Per trovare condizioni e aree di prova
- Per la manutenzione del software.
Contenuti
Una documentazione utile dovrebbe essenzialmente includere i seguenti contenuti:
High–level system architecture - Diagrammi di processo e diagrammi dei moduli
Key abstractions and mechanisms - Diagrammi di classe e diagrammi di oggetti.
Scenarios that illustrate the behavior of the main aspects - Diagrammi comportamentali
Caratteristiche
Le caratteristiche di una buona documentazione sono:
Conciso e allo stesso tempo inequivocabile, coerente e completo
Tracciabile in base alle specifiche dei requisiti del sistema
Well-structured
Diagrammatico invece che descrittivo