1967 Simula. 1970 SmallTalk. Poi C++, Delphi, Java e altri. La programmazione orientata agli oggetti è ormai il paradigma di sviluppo dominante, ma non solo: questo approccio influenza anche la fase di progettazione del software.
Sono Diego Purpo ed insieme cerchiamo di capire cosa si intende per Object Oriented Design.
Programmare ad oggetti significa creare un modello semplificato di una certa realtà rappresentato da entità digitali.
Ci sono gli oggetti concreti. Gli oggetti possono essere generalizzati e dare vita alle Classi. Gli oggetti utilizzano alcuni metodi per relazionarsi tra loro. Si genera reticolo di interazione tra oggetti che insieme forniscono soluzioni ai problemi.
Il disegno di un'applicazione è l'insieme delle attività di progettazione che, a partire dai requisiti funzionali rilevati in fase di analisi, identifica la migliore tra tutte le possibili soluzioni, in termini di manutenibilità, affidabilità, sicurezza, usabilità ed estendibilità.
Nel caso di progettazione basata sul paradigma ad oggetti parliamo di Object Oriented Design, o più comunemente OOD.
Un errore tipico è confondere il design con l'analisi: per quanto strettamente collegate e dipendenti, sono due momenti del ciclo di vita del software ben distinti.
L'Object Oriented Analysis, ha come scopo la definizione del cosa il sistema dovrà fare.
L'output di questa fase è solitamente un documento di requisiti funzionali, spesso in linguaggio naturale per essere compresi anche dal committente, rilevati attraverso lo strumento delle interviste al cliente.
I requisiti forniscono ai progettisti tutto il necessario per comprendere il problema ed il suo campo d'azione, detto dominio.
La fase di design è meno astratta e offre indicazioni che riguardano l'implementazione: il problema viene suddiviso in piccoli sottoproblemi di complessità inferiore. La scomposizione permetterà di definire le classi, gli oggetti, i loro attributi e le interazioni che li legheranno.
Una delle fasi più delicate del design è la ripartizione delle responsabilità tra gli elementi del sistema. Con l'espressione responsabilità si indicano i servizi che un oggetto può fornire, coerentemente al ruolo che gli è stato assegnato.
Esistono principalmente 2 categorie di responsabilità:
- responsabilità di fare: un oggetto fa qualcosa o avvia un processo
- responsabilità di conoscere: un oggetto ha accesso ad informazioni circa il proprio stato o l'ambiente
Nella scomposizione del problema e nell'assegnare le responsabilità si cerca di introdurre modelli di soluzione già utilizzati e di adattarli alle esigenze del caso. Questo approccio nel tempo ha portato ad emergere i modelli risolutivi più efficaci. Queste tecniche collaudate sono dette design pattern.
L'evoluzione dell'Object Oriented Design trasforma il modo di collaborare e di comunicare tra le diverse figure coinvolte nei progetti software. Nasce l'esigenza di uno strumento universale per la documentazione. Esigenza che dà vita, nel 1997, a UML, linguaggio di modellazione unificato.
Attraverso l'utilizzo di grafici e schemi logici, UML introduce gli standard di rappresentazione per ogni elemento del software.
Quando si conclude la fase di design è facile chiedersi se le scelte fatte abbiano portato ad un buon design.
È un'ardua domanda.
Un sistema ben progettato godrà certamente di 3 aspetti:
- Sarà flessibile, quindi sarà necessario modificare solo alcune sezioni di codice per far fronte ai cambiamenti, senza impatto sull'architettura
- Sarà robusto, perché una modifica non introdurrà danni o criticità nel sistema
- Sarà riusabile, perché basato su un buon livello di astrazione
Questi aspetti, sono strettamente legati a due indici di qualità del design: il basso accoppiamento, minima dipendenza tra le classi, e l'alta coesione, buona distribuzione delle funzionalità tra i componenti del sistema.
In conclusione è sempre preferibile un approccio al design semplice, in quanto introdurre troppa complessità può portare al over-engineering, che lede elasticità e manutenibilità del software.