Principi di Progettazione del Software a.a. 2016-2017 La progettazione orientata agli oggetti Prof. Luca Mainetti Università del Salento Obiettivi della lezione ■ Apprendere alcune tecniche per scomporre un sistema in moduli (oggetti) ■ Presentare le principali tipologie di relazioni che esistono tra i moduli (oggetti) ■ Vedere alcuni principi guida di modularizzazione (principalmente l’information hiding) ■ Riflettere su alcuni pattern architetturali e su alcuni stili di progettare le architetture software La progettazione orientata agli oggetti 2 Luca Mainetti Attività di progettazione ■ La progettazione – fornisce la struttura agli artefatti – permette di decomporre un sistema in parti – di assegnare le relative responsabilità – assicurare che le parti concorrano ai requisiti globali ■ Il risultato della progettazione è il modello dei sistema ■ L’architettura è la parte centrale del modello ■ Definisce un modo generale di procedere all’organizzazione di un modello in parti ■ La progettazione è il ponte tra requisiti e implementazione La progettazione orientata agli oggetti 3 Luca Mainetti Attività di progettazione (cont.) ■ La scomposizione di un sistema in moduli è la parte principale dell’attività di progettazione ■ Il documento di progettazione pone enfasi sull’organizzazione del sistema in moduli e sulle relazioni che esistono tra i moduli ■ Questo è ciò che si intende con “architettura software”: un insieme di moduli e di relazioni tra moduli che concorrono a realizzare un sistema comune (in termini di requisiti) ■ Saper progettare l’architettura del software è quindi fondamentale ■ Non vanno però persi di vista i requisiti: l’architettura “realizza i requisiti” La progettazione orientata agli oggetti 4 Luca Mainetti Architettura software ■ Mostra la struttura generale del sistema ■ I moduli che la compongono sono generalmente troppo “grandi” per poter essere mappati direttamente in software, ma sono già una linea guida importante per procedere nel raffinamento ■ La descrizione dell’architettura software include – i componenti principali del sistema – le relazioni tra questi componenti – il motivo e le ragioni per cui si è scelta tale scomposizione – vincoli che devono essere rispettati nella progettazione dei componenti La progettazione orientata agli oggetti 5 Luca Mainetti Architettura software (cont.) ■ Vi sono due obiettivi importanti ■ Progettazione per il cambiamento (Parnas) – il design si concentra sulle necessità espresse nei requisiti – una parte dell’effort è comunque dedicata ad anticipare possibili cambiamenti ■ Progettazione per famiglie di applicazioni (Parnas) – pensare che il sistema che si sta progettando non è una sola istanza, ma fa parte di una famiglia di programmi – gli esemplari della famiglia possono differenziarsi per versioni dovute a differenti ambienti di rilascio (device/canali) o a contesti di utilizzo La progettazione orientata agli oggetti 6 Luca Mainetti Progettazione per il cambiamento ■ E’ fondamentale saper progettare per il cambiamento ■ Il 60% del costo del software è per la manutenzione – correttiva – adattiva – perfettiva ■ Chi non progetta per il cambiamento – corre il rischio di spendere più effort per la manutenzione adattiva e perfettiva – compromette progressivamente la struttura logica del software per soddisfare le richieste di cambiamento quando queste emergono – rischia di peggiorare l’affidabilità del sistema La progettazione orientata agli oggetti 7 Luca Mainetti Alcune cause di cambiamento ■ Cambiamenti riguardanti gli algoritmi – ad esempio, sostituire un algoritmo di ordinamento con uno più efficiente – a proposito degli algoritmi, esiste un pattern di progettazione dedicato dal nome “strategy” che risolve il problema dell’incapsulamento di un algoritmo al fine di facilitarne la sostituibilità ■ Cambiamenti riguardanti la rappresentazione dei dati – ad esempio, passare da un albero binario ad un albero tramato – il 17% dei costi di manutenzione sono attribuibili a cambiamenti nella struttura dei dati (Lientz e Swanson, 1980) – il cambiamento nella struttura dati non ha solamente effetto sull’efficienza. Pensate, ad esempio, a strutture che permettono di aggiungere facilmente e velocemente informazioni (campi) in un file La progettazione orientata agli oggetti 8 Luca Mainetti Alcune cause di cambiamento (cont.) es: più efficienza nell’inserimento/cancellazione di record La progettazione orientata agli oggetti 9 Luca Mainetti Alcune cause di cambiamento (cont.) ■ Cambiamenti riguardanti la macchina astratta sottostante – nuove versioni di sistema operativo – nuove versioni (ottimizzate) dei compilatori – nuove versioni di DBMS – ecc. ■ Cambiamenti dovuti a periferiche e device – molto importante ora che nuove periferiche d’interazione si stanno affermando ■ Cambiamenti dovuti al contesto – ad esempio, nuovo regime fiscale, passaggio all’Euro per un sistema che si occupa di transazioni finanziarie ■ Cambiamenti dovuti al processo di sviluppo – trasformazioni di prototipi in prodotti in un processo incrementale La progettazione orientata agli oggetti 10 Luca Mainetti Alcune tecniche specifiche di progettazione per il cambiamento ■ Costanti di configurazione – nel codice di moduli dedicati – in file esterni ■ Compilazione condizionale – ad esempio, se ci fossero due configurazioni differenti di hardware • # ifdef hardware-1 ...source fragment for hardware 1 ... # endif #ifdef hardware-2 ...source fragment for hardware 2 ... # endif ■ Generatori di codice – generatori di logica per domini specifici – generatori di interfacce utente – generatori della struttura di moduli per linguaggi specifici La progettazione orientata agli oggetti 11 Luca Mainetti Moduli e architettura ■ Un modulo è uno dei sottosistemi che compongono un’applicazione software ■ La progettazione di un’applicazione riguarda quindi la progettazione dei moduli e delle mutue interrelazioni ■ Un modulo è una porzione di software dotata di una sua memoria persistente. E’ quindi qualcosa di più di una semplice routine la cui memoria perde di significato quando lo stack viene deallocato ■ Un modulo è una porzione di software che contiene e fornisce risorse e servizi computazionali La progettazione orientata agli oggetti 12 Luca Mainetti Moduli e architettura (cont.) ■ I principali criteri per una buona modularizzazione sono la valutazione del grado di coesione e del disaccoppiamento ■ Coesione – è il grado di unità e di legami interni tra gli elementi di un modulo – un modulo coeso è fatto da elementi omogenei – un modulo coeso è facilmente comprensibile, è facilmente realizzabile, rende facilmente modificabile l’intero sistema poiché gli interventi sono localizzati ■ Disaccoppiamento – è il grado di indipendenza tra moduli distinti – quanto più i moduli sono disaccoppiati, tanto più sono facili da comprendere e da realizzare indipendentemente poiché la comprensione di un modulo non richiede la comprensione degli altri – moduli disaccoppiati hanno pochi e semplici legami La progettazione orientata agli oggetti 13 Luca Mainetti Moduli e architettura (cont.) ■ L’insieme delle interrelazioni tra i moduli viene detta architettura del sistema ■ In realtà, quando si definisce un’architettura software, si definiscono contemporaneamente moduli ed interrelazioni. L’identificazione dei moduli non può essere ovviamente disgiunta dall’individuazione delle mutue dipendenze ■ L’architettura di un sistema viene generalmente rappresentata tramite grafi diretti (la direzione indica il verso delle dipendenze) – G = <N, A> – N è l’insieme dei nodi – A ⊆ N x N è l’insieme degli archi (l’ordine è importante nella specifica delle dipendenze) La progettazione orientata agli oggetti 14 Luca Mainetti Moduli e architettura (cont.) ■ Siamo generalmente interessati a grafi aciclici – una sequenza <n1, n2>,<n3, n4>, …,<nk-1, nk> di archi di un grafo è un ciclo se n1=nk, cioè se si ha un cammino chiuso – un grafo diretto aciclico viene detto gerarchia. In una gerarchia i nodi possono essere classificati per livelli – spesso siamo anche interessati a particolari grafi aciclici. In un albero esiste uno ed un solo cammino diretto che collega la radice con ciascuno degli altri nodi A B E A C F D B G H La progettazione orientata agli oggetti E Grafo C F G H 15 D Albero Luca Mainetti La relazione USA ■ La relazione USA è una di quelle più spesso ricorrenti tra i moduli ■ Tale relazione evidenzia quali sono i servizi che un modulo mette a disposizione agli altri, e quali sono i servizi che ogni singolo modulo richiede agli altri ■ E’ quindi la struttura logica più importante di un’architettura di sistema ■ ni USA nj se perché il modulo ni risulti corretto rispetto alle specifiche è necessaria anche la corretta esecuzione di nj ■ In altri termini ni risulta cliente dei servizi di nj La progettazione orientata agli oggetti 16 Luca Mainetti La relazione USA (cont.) ■ La relazione USA sta tra due estremi – USA = M x M • tutti i moduli del sistema sono in relazione USA • il grado di disaccoppiamento del sistema è troppo basso – USA = ∅ • nessun modulo usa servizi di nessun altro • il sistema è fatto di sottosistemi isolati in cui è presumibile che siano replicate varie funzionalità, quindi il livello di coesione è scarso ■ Si deve trovare il giusto equilibrio tra i due estremi – un modulo deve fare uso di un numero limitato di risorse di altri moduli (il modulo risulta più facilmente comprensibile da solo), quindi il numero di archi uscenti deve essere basso – un modulo deve ricevere invece parecchie richieste dall’esterno (i servizi sono stati fattorizzati), quindi il numero di archi entranti deve essere elevato La progettazione orientata agli oggetti 17 Luca Mainetti La relazione USA (cont.) ■ La relazione USA non si esaurisce con la sola chiamata di metodo o di procedura ■ Vanno considerate situazioni in cui i moduli si scambino messaggi oppure condividano strutture dati ■ Questa osservazione è molto importante vista la costante evoluzione tecnologica e dei linguaggi di programmazione ■ I moduli che si scambiano messaggi ed i moduli che usano strutture condivise sono in relazione USA La progettazione orientata agli oggetti 18 Luca Mainetti La relazione USA (cont.) ■ Nella progettazione di sistemi concreti, è utile che la relazione USA sia aciclica. In altri termini è utile che l’architettura del sistema sia gerarchica ■ In una gerarchia si dice che mi è ad un livello di astrazione maggiore di mj sei il suo livello rispetto alla gerarchia USA è minore del livello di mj ■ Un sistema gerarchico può essere analizzato dal livello più alto di astrazione: per comprendere un modulo è sufficiente avere conoscenza dei moduli utilizzati ■ Un sistema gerarchico può essere realizzato, integrato e verificato per parti ■ Si evitano quindi i casi pericolosi in cui nulla funziona finché tutto funziona La progettazione orientata agli oggetti 19 Luca Mainetti La relazione COMPONENTE_DI ■ Una relazione ortogonale a USA è COMPONENTE_DI ■ In questo caso si rappresenta il raffinamento progressivo di un modulo in sottomoduli ■ COMPONENTE_DI ⊆ M x M – tale relazione deve dare luogo necessariamente ad una gerarchia – la gerarchia non deve essere necessariamente un albero, ma in generale può contenere collegamenti diretti anche tra livelli non contigui ■ Tra tutti i moduli appartenenti ad una relazione COMPONENTE_DI solamente quelli terminali esistono effettivamente nel sistema. I moduli intermedi servono per il raffinamento del sistema e per la sua documentazione La progettazione orientata agli oggetti 20 Luca Mainetti La relazione COMPONENTE_DI (cont.) ■ Una volta che un modulo che appartiene alla relazione USA viene scomposto in sottomoduli, devono essere anche ridefiniti gli archi USA sui sottomoduli stessi A B E A C F a1 a2 a1 a3 a2 F a3 B C D I: specifica di USA La progettazione orientata agli oggetti II: specifica di COMPONENTE_DI 21 III: ridefinizione di USA per i moduli coinvolti Luca Mainetti Costruzione incrementale e differimento decisioni ■ Vi sono evidenti vantaggi derivanti dalla costruzione incrementale del software ■ La costruzione incrementale è facilitata dall’individuazione di moduli. Spesso ricade in un processo di sviluppo iterativo ■ Se si utilizza un approccio top-down frequentemente però si tende ad anticipare decisioni che condizionano la struttura dell’intero progetto (ad esempio, i protocolli, le strutture dati) ■ Per garantire modificabilità e flessibilità, le decisioni vanno prese solamente quando si hanno tutti gli elementi a disposizione ■ Il differimento delle decisioni viene condotto con tecniche di information hiding La progettazione orientata agli oggetti 22 Luca Mainetti Information hiding ■ Una volta definita l’architettura di sistema, con le relazioni USA e COMPONENTE_DI, prima di procedere all’implementazione è necessario entrare maggiormente nel dettaglio della progettazione delle effettive relazioni che legano i moduli ■ In sostanza devono essere definite le interfacce dei moduli, cioè l’insieme dei servizi messi a disposizione ■ Il contenuto del modulo (anche detto realizzazione o implementazione) rimane invisibile dall’esterno. Deve poter essere deciso localmente e non deve dipendere dagli altri moduli ■ Questo in sintesi è il concetto di information hiding – interfaccia (risorse esportate, risorse importate) – realizzazione La progettazione orientata agli oggetti 23 Luca Mainetti Information hiding (cont.) ■ Sono principalmente le scelte di progetto locali (interne al modulo) che devono essere tenute nascoste, così che possa essere garantita la modificabilità ■ Ad esempio, tipiche scelte locali possono essere – gli algoritmi utilizzati (non è utile che un modulo cliente conosca i dettagli degli algoritmi utilizzati da un modulo servente per fornire servizi) – le strutture dati locali (differente è ovviamente il discorso per le strutture dati condivise) – le politiche di assegnamento delle risorse ■ L’elenco sopra riportato è ampiamente incompleto e puramente indicativo La progettazione orientata agli oggetti 24 Luca Mainetti Notazione di progetto ■ La notazione utilizzata per la specifica del progetto è di enorme importanza ■ Deve essere funzionale all’efficienza del team di sviluppo ed alla comunicazione verso altre tipologie di stakeholder ■ Esistono notazioni testuali (ispirate ai linguaggi di programmazione) e notazioni grafiche ■ Spesso si usano più notazioni in un medesimo progetto, poiché, ad esempio, si deve specificare – la struttura informativa – l’interazione con l’utente – l’interfaccia grafica – le operazioni messe a disposizione La progettazione orientata agli oggetti 25 Luca Mainetti Modularizzazione come contrattazione ■ Spesso durante l’attività di progettazione si è in dubbio se alcune funzionalità siano da affidare al modulo cliente oppure a quello servente ■ Tipicamente ciò accade nella gestione delle eccezioni ■ Una linea guida per la corretta scelta fa uso di un procedimento di contrattazione: si deve stabilire un contratto su reciproci obblighi e responsabilità – il modulo servente si obbliga a prestare il servizio – il modulo cliente si impegna a mettere il servente nelle condizioni migliori perché il servizio si svolga, cioè a rispettare i vincoli posti dal servente ■ La definizione dei moduli deve quindi contenere non solo la specifica delle interfacce, ma anche i vincoli d’uso La progettazione orientata agli oggetti 26 Luca Mainetti Modularizzazione come contrattazione (cont.) ■ Se si demanda il controllo del rispetto dei vincoli d’uso al servente, lo si appesantisce di verifiche che non gli spettano. E’ meglio affidarli al cliente del servizio ■ In modo analogo, si deve stabilire chi ha l’obbligo di trattare le eccezioni, cioè il comportamento del software a fronte di situazioni anomale ■ In questo caso è conveniente che il modulo servente si limiti a segnalare il verificarsi di un eccezione, mentre il trattamento della stessa sia una responsabilità del modulo cliente ■ Questa scelta permette di gestire l’eccezione nel contesto della chiamata del servizio che l’ha generata – solamente in tale contesto si dispongono di tutti i dati per una completa gestione, i quali altrimenti dovrebbero essere passati al modulo servente rendendolo inutilmente complicato La progettazione orientata agli oggetti 27 Luca Mainetti I moduli come astrazione sul controllo ■ Nei linguaggi di programmazione tradizionali i moduli corrispondono alle subroutine ■ In questo caso il modulo è soprattutto un’astrazione del controllo: infatti le subroutine non nascondono totalmente i dati su cui operano (pensate a variabili globali e quindi agli effetti collaterali), altrimenti al loro termine le operazioni non avrebbero effetto, ma nascondono soprattutto il flusso di controllo delle istruzioni, cioè gli algoritmi ■ Le subroutine permettono di realizzare una particolare classe di moduli detta librerie: procedure spesso utilizzate, molto efficienti, affidabili e facilmente comprensibili La progettazione orientata agli oggetti 28 Luca Mainetti I moduli come astrazione sui dati ■ Però la information hiding deve essere estesa anche ai dati ■ Al livello più basso si ha il raggruppamento di dati in modo da centralizzarne l’accesso – si pensi ad un modulo che contiene i dati di configurazione di un sistema software ■ Poi l’astrazione può procedere in due direzioni ortogonali in termini di riusabilità, flessibilità, genericità Tipizzazione Oggetti Tipi di dati astratti Oggetti generici Tipi di dati astratti generici Genericità La progettazione orientata agli oggetti 29 Luca Mainetti Oggetti ■ Un oggetto è un modo di incapsulare dati (attributi) in un modulo, regolandone l’accesso tramite opportune procedure (metodi) ■ Un oggetto deve essere caratterizzato agli effetti esterni soltanto dalla sua interfaccia ■ Però una visione puramente funzionale non è sufficiente. Il comportamento di un oggetto è anche dato dal suo stato. Oggetti con la medesima interfaccia, ma che si trovano in stati differenti possono avere comportamenti differenti ■ La dipendenza dei risultati delle elaborazioni dallo stato differenzia gli oggetti dalle librerie; le librerie forniscono solamente funzionalità, non contengono dati La progettazione orientata agli oggetti 30 Luca Mainetti Tipi di dati astratti ■ Un tipo di dato astratto è in estrema sintesi il concetto di tipo di variabile applicato ad un oggetto ■ Una classe è un modo di rappresentare un tipo di dato astratto ■ Una classe è un’astrazione di tipizzazione di un oggetto ■ Una classe è un tipo di oggetto ■ Un tipo di dato astratto è quindi un modulo che incapsula sia la definizione di un tipo, la cui struttura risulta invisibile all’esterno, sia l’insieme delle operazioni che permettono di manipolare gli oggetti (istanze) di quel tipo La progettazione orientata agli oggetti 31 Luca Mainetti Oggetti generici ■ Un oggetto generico non incapsula direttamente dei dati e le relative procedure d’accesso, ma piuttosto fornisce uno schema (template) di incapsulamento ■ E’ un’astrazione utile in tutti in quei casi in cui la manipolazione di un oggetto “composto” non dipende dalla natura dei suoi “componenti” ■ Pensiamo ad una tabella ed alle procedure di manipolazione: sono indipendenti dalla natura degli elementi della tabella ■ Un oggetto generico è quindi parametrico rispetto al suo tipo e per poter essere usato deve essere prima istanziato La progettazione orientata agli oggetti 32 Luca Mainetti Oggetti generici (cont.) ■ Qui segue un esempio di istanziazione in pseudo-codice – generic module TabellaGenerica(TipoElemento); – module TabellaDiInteri is TabellaGenerica(Integer); ■ Si può verificare che per manipolare correttamente i dati un oggetto generico debba comunque far ricorso ad informazioni sull’effettivo tipo rispetto al quale è parametrico ■ Un oggetto generico può quindi esserlo anche rispetto alle funzionalità – generic module TabellaGenerica(TipoElemento) with Ordinamento(Elemento: TipoElemento); – modulo TabellaDiInteri is TabellaGenerica(Integer) with Crescente(Integer); – modulo TabellaDiPersone is TabellaGenerica(Persona) with Crescente(Persona); La progettazione orientata agli oggetti 33 Luca Mainetti Architetture standard ■ Si possono riscontrare alcune architetture ricorrenti pipeline – pipeline – blackboard: un modulo fa comunicare tutti gli altri – basate su eventi: soddisfano il paradigma “pubblicazionesottoscrizione”; alcuni moduli pubblicano (generano) eventi, altri si registrano (si sottoscrivono) blackboard – specifiche di dominio: tengono conto delle caratteristiche di determinati domini applicativi La progettazione orientata agli oggetti eventi 34 Luca Mainetti Architetture standard (cont.) ■ Un esempio molto noto di un’architettura specifica di dominio è “model-view-controller” ■ Si presta a risolvere situazioni in cui è rilevante l’interazione con l’utente La progettazione orientata agli oggetti 35 Luca Mainetti