Concetto: Meccanismi di progettazione ed implementazione
Un meccanismo di progettazione aggiunge dei dettagli concreti al meccanismo concettuale di analisi ma evita la richiesta di particolari tecnologie.
Relazioni
Descrizione principale

Introduzione ai meccanismi di progettazione e di implementazione

Un meccanismo di progettazione è il perfezionamento di un corrispondente meccanismo di analisi(consultare anche Concetto: Meccanismi di analisi). Un meccanismo di progettazione aggiunge dettagli concreti al meccanismo di analisi concettuale ma evita la richiesta di tecnologia particolare - ad esempio, un'implementazione particolare di un fornitore relativa ad un sistema di gestione database orientato sugli oggetti. Come per i meccanismi di analisi, un meccanismo di progettazione può creare istanze di uno o più pattern, in questo caso pattern strutturali o di progettazione.

In modo simile, un meccanismo di implementazione è un perfezionamento di un corrispondente meccanismo di progettazione, che utilizza, ad esempio, un linguaggio di programmazione particolare e diversa tecnologia di implementazione (ad esempio un particolare prodotto middleware del fornitore). Un meccanismo di implementazione può creare l'istanza di uno o più idiomi o pattern di implementazione.

Esempio: Caratteristiche dei meccanismi di progettazione

Si prenda in considerazione il meccanismo di analisi di Persistenza:

  • Potrebbe essere necessario memorizzare per alcuni secondi molti (2.000) oggetti piccoli (200 byte ognuno), senza bisogno che sopravvivano.
  • Potrebbe essere necessario memorizzare permanentemente alcuni oggetti molto grandi sul disco per diversi mesi, mai aggiornati ma con sofisticati mezzi di richiamo.

Questi oggetti richiederanno un supporto di persistenza diverso; potrebbero essere identificate le seguenti caratteristiche di meccanismi di progettazione per il supporto di persistenza:

  • Memorizzazione In-memory; caratteristiche: per un massimo di 1 Mb totale (dimensione x volume); accesso molto veloce per lettura, scrittura, aggiornamento.
  • Flash card; caratteristiche: fino a 8 Mb; accesso lento per aggiornamento e scrittura; accesso moderato per la lettura.
  • File binario; caratteristiche: da 100 Kb a 200 Mb; aggiornamento lento; accesso lento per lettura e scrittura.
  • Database Management System (DBMS); caratteristiche: da 100 Kb a salire (essenzialmente senza limite massimo); aggiornamento, lettura e scrittura ancora più lenti.

Queste velocità sono giudicate 'lente' in relazione alla memorizzazione di tipo in-memory.  Ovviamente, in alcuni ambienti, l'utilizzo della cache può migliorare i tempi di accesso apparenti.

Il diagramma è descritto nel contenuto.



Perfezionamento della mappatura fra i meccanismi di progettazione e di implementazione

Inizialmente, la mappatura fra i meccanismi di progettazione e quelli di implementazione è probabilmente meno che ottimale ma sufficiente ad eseguire il progetto, identificare i rischi non ancora rilevati ed attivare ulteriori indagini e valutazioni. Col proseguire del progetto e l'aumentare della conoscenza, la mappatura deve essere perfezionata.

Procedere iterativamente per perfezionare la mappatura fra i meccanismi di progettazione e di implementazione, eliminando i percorsi ridondanti, lavorando sia dall'alto verso il basso che viceversa.

Lavorare dall'alto verso il basso Quando si lavora "dall'alto verso il basso", nuove realizzazioni perfezionate di casi d'uso collocano dei nuovi requisiti sui necessari meccanismi di progettazione tramite i meccanismi di analisi necessari. I nuovi requisiti potrebbero mettere a nudo ulteriori caratteristiche di un meccanismo di progettazione, forzando una separazione fra i meccanismi. Esiste anche un compromesso fra la complessità del sistema e le sue prestazioni:

  • Troppi meccanismi di progettazione diversi rendono il sistema troppo complesso.
  • Pochi meccanismi di progettazione possono creare delle problematiche di prestazione ad alcuni meccanismi di implementazione che allungano i limiti degli intervalli ragionevoli dei relativi valori delle caratteristiche.

Lavorare dal basso verso l'alto. Quando si lavora "dal basso verso l'alto", indagando sui meccanismi di implementazione disponibili, è possibile trovare dei prodotti che soddisfano immediatamente diversi meccanismi di progettazione, ma forzano un certo adattamento o una ripartizione del meccanismo di progettazione. Si desidera ridurre al minimo il numero di meccanismi di implementazione utilizzati ma anche il fatto che siano troppo pochi può portare a problematiche di prestazione.

Una volta deciso di utilizzare un DBMS per memorizzare gli oggetti di classe A, si potrebbe essere tentati dall'utilizzarlo per memorizzare tutti gli oggetti del sistema. Questo potrebbe rivelarsi molto inefficiente, o molto scomodo. Non tutti gli oggetti che richiedono persistenza devono essere memorizzato nel DBMS. Alcuni oggetti possono essere permanenti ma potrebbero essere acceduti spesso dall'applicazione e solo raramente acceduti da altre applicazioni. Il migliore approccio potrebbe essere una strategia ibrida, in cui l'oggetto viene letto dal DBMS nella memoria e sincronizzato periodicamente.

Esempio

Un volo potrebbe essere memorizzato in memoria per un accesso rapido, e in un DBMS per una persistenza a lungo termine; questo, tuttavia, attiva per il meccanismo l'esigenza di dover sincronizzare entrambi.

Non è inusuale disporre di più di un meccanismo di progettazione associato ad una classe client come compromesso fra le differenti caratteristiche.

Poiché i meccanismi di implementazione spesso sono forniti in gruppi nei componenti già pronti (sistemi operativi e prodotti middleware) devono essere eseguite alcune ottimizzazioni in base ai costi o a mancata corrispondenza di impedenza o uniformità di stile. Inoltre i meccanismi spesso sono interdipendenti, cosa che rende difficile una netta separazione dei servizi nei meccanismi di progettazione.

Esempi

  • Il meccanismo di notifica può essere basato sul meccanismo di comunicazione fra processi.

  • Il meccanismo di segnalazione errori può essere basato sul meccanismo di persistenza.

Il perfezionamento continua nell'intera fase di elaborazione ed è sempre un compromesso fra:

  • Un'esatta 'corrispondenza' con i requisiti dei client del meccanismo di progettazione, in termini di caratteristiche previste.
  • Il costo e la complessità di avere troppi meccanismi di implementazione da acquisire ed integrare.

L'obiettivo generale è sempre di avere un insieme semplice pulito di meccanismi che forniscono ad un sistema di grandi dimensioni integrità concettuale, semplicità ed eleganza.

Esempio: Mappatura dei meccanismi di progettazione con i meccanismi di implementazione

I meccanismi di progettazione Persistenza possono essere messi in corrispondenza con i meccanismi di implementazione nel modo seguente:

Il diagramma è descritto nel contenuto.

Una possibile mappatura fra i meccanismi di analisi e i meccanismi di progettazione. Le frecce tratteggiate significano "viene specializzato da", implicando che le caratteristiche dei meccanismi di progettazione vengono ereditati dai meccanismi di analisi ma che verranno specializzati e perfezionati.

Una volta terminata l'ottimizzazione dei meccanismi, esistono le seguenti mappature:

Il diagramma è descritto nel contenuto.

Le decisioni di progettazione per una classe client in termini di mappature fra i meccanismi; la classe Flight necessita di due forme di persistenza: memorizzazione in-memory implementata da una routine di libreria già pronta, e in un database implementato con un prodotto ObjectStorage acquistabile.

La mappa deve essere esplorabile in entrambe le direzioni, in modo che sia facile individuare le classi client quando si cambiano i meccanismi di implementazione.

Descrizione dei meccanismi di progettazione

I meccanismi di progettazione e i dettagli relativi al loro utilizzo sono documentati nel Prodotto di lavoro: Linee guida specifiche per progetto. La relazione (o mappatura) fra i meccanismi di analisi, quelli di progettazione, quelli di implementazione ed il fondamento logico associato alle scelte, è documentata nel Prodotto di lavoro: Documento dell'architettura software.

Come per i meccanismi di analisi, i meccanismi di progettazione possono essere modellati utilizzando una collaborazione, che può creare istanze di uno o più pattern strutturalio di progettazione.

Esempio: un meccanismo di persistenza

Questo esempio utilizza l'istanza di un pattern per una persistenza basata su RDBMS preso da JDBC™ (Java Data Base Connectivity).  Anche se qui viene presentata la progettazione, JDBC fornisce il codice effettivo per alcune delle classi, quindi il passo da quello che viene presentato qui ad un meccanismo di implementazione, è breve.

La figura Vista statica: JDBC mostra le classi (esattamente, i ruoli del classificatore) nella collaborazione.

Il diagramma è descritto nel contenuto.

Vista statica: JDBC

Le classi gialle sono quelle che sono state fornite, le altre (myDBClass ecc.) sono state collegate dal progettista per creare il meccanismo.

In JDBC, un client utilizzerà una DBClass per la lettura e la scrittura di dati permanenti. La DBClass è responsabile dell'accesso al database JDBC tramite la classe DriverManager. Una volta aperta una Connessione al database, la DBClass può creare istruzioni SQL che verranno inviate al RDBMS sottostante ed eseguita utilizzando la classe Statement. La classe Statement è quella che "dialoga" con il database. Il risultato della query SQL viene restituito in un oggetto ResultSet. 

La classe DBClass deve rendere permanente un'altra istanza di classe. Comprende la mappatura da-OO-a-RDBMS ed ha la funzionalità di interfaccia con RDBMS. La DBClass appiattisce l'oggetto, lo scrive in RDBMS, legge i dati dell'oggetto  da RDBMS e crea l'oggetto. Ogni classe permanente avrà una DBClass corrispondente. 

PersistentClassList viene utilizzato per restituire un insieme di oggetti permanenti come risultato di una query del database (ad es., DBClass.read()).

Ora viene presentata una serie di viste dinamiche per mostrare come funziona effettivamente il meccanismo.

Il diagramma è descritto nel contenuto.

JDBC: Inizializzazione

L'inizializzazione deve verificarsi prima di poter accedere a qualunque classe permanente.

Per inizializzare la connessione al database, DBClass deve caricare il driver appropriato richiamando l'operazione DriverManager getConnection() con URL, utente e password.

L'operazione getConnection() tenta di stabilire una connessione all'URL di database fornito. DriverManager tenta di selezionare un driver appropriato dalla serie di driver JDBC registrati.

Parametri:

url: un url di database nel formato jdbc:subprotocol:subname. Questo URL viene utilizzato per individuare il server di database effettivo e in questa istanza non è correlato a Web.

utente: l'utente del database per conto del quale è stata effettuata la connessione

pass: la password dell'utente

Restituisce:

una connessione all'URL.

Il diagramma è descritto nel contenuto.

JDBC: Creazione

Per creare una nuova classe, il client di persistenza chiede alla DBClass di crearla. La DBClass crea una nuova istanza di PersistentClass con i valori predefiniti. La DBClass quindi crea una nuova istruzione utilizzando l'operazione createStatement() della classe Connectiion. L'istruzione viene eseguita e i dati vengono inseriti nel database.

Il diagramma è descritto nel contenuto.

JDBC: Lettura

Per leggere una classe permanente, il client di persistenza chiede alla DBClass di leggere. La DBClass crea una nuova istruzione utilizzando l'operazione createStatement() della classe Connection. L'istruzione viene eseguita ed i dati vengono restituiti in un oggetto ResultSet. La DBClass quindi crea una nuova istanza di PersistentClass e la popola con i dati richiamati. I dati vengono restituiti in un oggetto di raccolta, un'istanza della classe PersistentClassList.

Nota: la stringa passata a executeQuery() non è necessariamente esattamente la stessa passata nell'operazione read(). DBClass crea la query SQL per richiamare i dati permanenti dal database, utilizzando i criteri passati nell'operazione read(). Questo avviene perché il client di DBClass non debba dover conoscere l'interno del database per creare una query valida. Questa conoscenza è incapsulata all'interno della DBClass.

Il diagramma è descritto nel contenuto.

JDBC: Aggiornamento

Per aggiornare una classe, il client di persistenza chiede a DBClass di aggiornare. DBClass richiama i dati dall'oggetto PersistentClass fornito crea una nuova istruzione utilizzando l'operazione createStatement() della classe Connection. Una volta creata l'istruzione, viene eseguito l'aggiornamento ed il database viene aggiornato con i nuovi dati provenienti dalla classe.

Attenzione: è compito della DBClass "appiattire" la PersistentClass e scriverla nel database. Questo è il motivo per cui deve essere richiamata dalla PersistentClass specificata, prima di poter creare l'istruzione SQL.

Nota: nel meccanismo appena descritto, PersistentClass deve fornire le routine di accesso per tutti i dati permanenti perché DBClass possa accedervi. Questo fornisce l'accesso esterno a determinati attributi permanenti che altrimenti sarebbero stati privati. Questo è il prezzo da pagare per estrarre la conoscenza della persistenza dalla classe che incapsula i dati.

Il diagramma è descritto nel contenuto.

JDBC: Eliminazione

Per eliminare una classe, il client di persistenza chiede a DBClass di eliminare PersistentClass. La DBClass crea una nuova istruzione utilizzando l'operazione createStatement() della classe Connection. L'istruzione viene eseguita e i dati vengono rimossi dal database.

Nell'implementazione di questa progettazione, verrebbero prese alcune decisioni relative alla mappatura di DBClass con le classi permanenti, ad es. disponendo una DBClass per classe permanente ed assegnandole ai pacchetti appropriati.  Questi pacchetti avranno una dipendenza sul pacchetto java.sql fornito (consultare JDBC Documentazione API) che contiene le classi di supporto DriverManager, Connection, Statement e ResultSet.