appunti3s:relazioni_tra_classi
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
appunti3s:relazioni_tra_classi [2013/09/12 09:38] – profpro | appunti3s:relazioni_tra_classi [2020/06/08 22:20] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | > torna al menù principale > [[appunti3s: | ||
+ | |||
+ | ====== Relazioni ta classi ====== | ||
+ | |||
+ | La // | ||
+ | (mentre i legami tra gli //oggetti// questi legami sono implementati con i // | ||
+ | |||
+ | * Ha il **vantaggio** di consentire un riutilizzo del codice delle classi. | ||
+ | * Ha lo **svantaggio** di creare accoppiamento e dipendenza del codice delle classi. | ||
+ | |||
+ | ===== Tipologie ===== | ||
+ | Esistono diversi tipi di relazioni tra classi. Ogni tipo può essere descritto dalle seguenti caratteristiche: | ||
+ | - Ogni relazione possiede: un nome e (uno o più) versi di navigabilità | ||
+ | - Ogni classe coinvolta in una relazione può avere: un ruolo e una molteplicità | ||
+ | |||
+ | In questa tabella si utilizza la simbologia dello standard [[appunti3s: | ||
+ | |||
+ | ^ relazione ^ verbo ^ verbo ^ n.versi ^ implementazione ^ simbolo ^ | ||
+ | | [[appunti3s: | ||
+ | | [[appunti3s: | ||
+ | | [[appunti3s: | ||
+ | | [[appunti3s: | ||
+ | | [[appunti3s: | ||
+ | | [[appunti3s: | ||
+ | |||
+ | Fare esempi e confronti di relazioni tra classi (fatte bene e fatte male) | ||
+ | |||
+ | ===== Traduzione ===== | ||
+ | |||
+ | Nel linguaggio C++ le relazioni tra classi possono essere tradotte usando diverse tecniche di programmazione orientata agli oggetti: | ||
+ | |||
+ | * una classe può essere definita dentro una classe (nested) (composizione) | ||
+ | * una classe può essere definita fuori da una classe e instanziata dentro quella classe | ||
+ | * come oggetto membro (aggregazione) | ||
+ | * come puntatore o reference membro (associazione) | ||
+ | * una classe può essere derivata a partire da un' | ||
+ | |||
+ | In questa ampia scelta, sono da privilegiare le relazioni più deboli perché sono più semplici e creano una minore dipendenza tra i moduli. | ||
+ | Quale tra quelle citate è la relazione più debole e quale quella più forte? | ||
+ | L' | ||
+ | |||
+ | |||
+ | ====== Composizione ====== | ||
+ | {{: | ||
+ | * una linea continua con il simbolo del rombo pieno appoggiato alla classe // | ||
+ | * i numerini indicano la molteplicità | ||
+ | * Ha sempre DUE versi di percorrenza (quindi due regole) | ||
+ | * l' | ||
+ | |||
+ | ===== Principio | ||
+ | * La classe del componente può andar a comporre una sola classe contenitore | ||
+ | * Non si possono creare nuovi oggetti senza creare prima il loro oggetto contenitore | ||
+ | ===== Descrizione ===== | ||
+ | |||
+ | Il verbo usato per descrivere questa relazione è //has//: possedere, avere, essere composto da... | ||
+ | Nella Composizione le classi componenti esistono solo in relazione alla classe contenitore. Non si possono creare oggetti al di fuori di tali classi. | ||
+ | |||
+ | ===== Come si realizza? ===== | ||
+ | Poiché la relazione è forte è necessario dichiarare una classe nel namespace di una classe contenitore. | ||
+ | In questo modo è realizzato anche il principio dell' | ||
+ | < | ||
+ | Class A | ||
+ | { | ||
+ | | ||
+ | Class B | ||
+ | { | ||
+ | }; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | In questo modo tutte le funzioni membro della classe contenitore hanno accesso a tutti i dati membro dell' | ||
+ | Se gli oggetti sono creati nello stack verranno inizializzati/ | ||
+ | |||
+ | Se è necessario usare più volte questi oggetti (come 4 gambe di un tavolo) si possono usare vector. | ||
+ | |||
+ | Non confondere la molteplicità con il numero di versi di navigabilità. | ||
+ | < | ||
+ | Se la molteplicità è maggiore di uno si implementa con i vettori</ | ||
+ | |||
+ | ===== Esempio ===== | ||
+ | |||
+ | Codice sorgente con esempio di {{: | ||
+ | |||
+ | ===== Esercizio ===== | ||
+ | Creare le classi per disegnare punti e segmenti sul piano cartesiano. | ||
+ | Lo stesso esempio può essere risolto: | ||
+ | * con l' | ||
+ | * con la composizione se considero di creare due nuovi punti per ogni segmento (non rappresento punti singoli) | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Aggregazione ====== | ||
+ | {{: | ||
+ | * una linea continua con il simbolo del rombo vuoto vicino alla classe // | ||
+ | * i numerini indicano la molteplicità | ||
+ | * Ha sempre UNO SOLO verso di percorrenza (quindi una regola) | ||
+ | * la Composizione ha il simbolo del rombo pieno. | ||
+ | |||
+ | ===== Principio ===== | ||
+ | Il verbo usato per descrivere questa relazione è //has//: possedere, avere, essere composto da... | ||
+ | Nell' | ||
+ | |||
+ | ===== Come si realizza? ===== | ||
+ | Possedere un oggetto significa avere un oggetto membro di quel tipo... | ||
+ | Le classi componenti esistono indipendentemente dalla classe contenitore, | ||
+ | Se la molteplicità è maggiore di uno si implementa con array di puntatori o vector (i vector lavorano per copia) | ||
+ | </ | ||
+ | < | ||
+ | class B | ||
+ | { | ||
+ | //... | ||
+ | }; | ||
+ | |||
+ | class A | ||
+ | { | ||
+ | | ||
+ | B m_b; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Esempio ===== | ||
+ | File sorgenti di un esempio di {{: | ||
+ | |||
+ | ===== Esercizio ===== | ||
+ | Creare le classi per disegnare punti e segmenti sul piano cartesiano. | ||
+ | Lo stesso esempio può essere risolto: | ||
+ | * con l' | ||
+ | * con la composizione se considero di creare due nuovi punti per ogni segmento (non rappresento punti singoli) | ||
+ | * | ||
+ | ====Analisi del problema==== | ||
+ | - il segmento può essere creato a partire da punti pre-esistenti? | ||
+ | - cosa accade al punto se distruggo il segmento? | ||
+ | - cosa accade al segmento se distruggo un suo punto? | ||
+ | - un punto può appartenere a due segmenti contemporaneamente? | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Associazione ====== | ||
+ | {{: | ||
+ | * La relazione di Associazione si rappresenta con una o due frecce su una linea continua. | ||
+ | * L' | ||
+ | * I numerini indicano la molteplicità minima e massima (0..3, 1, *) | ||
+ | * Le classi possono avere un ruolo | ||
+ | * __Può avere due versi__ di navigabilità (una o due frecce sulla linea), cioè DUE regole | ||
+ | * La relazione di Dipendenza si rappresenta con la freccia a linea tratteggiata. (classi astratte??? | ||
+ | ===== Principio ===== | ||
+ | Il verbo usato per descrivere questa relazione è //uses//: utilizzare | ||
+ | |||
+ | ===== Come si realizza? ===== | ||
+ | Se A e B sono in relazione di associazione, | ||
+ | - avere funzioni che hanno come argomenti copie, puntatori o reference a oggetti di tipo B | ||
+ | - avere funzioni che restituiscono copie, puntatori o reference a oggetti di tipo B. | ||
+ | - avere membri di tipo reference o puntatori a oggetti di tipo B | ||
+ | < | ||
+ | Class B; // nell' | ||
+ | |||
+ | Class A | ||
+ | { | ||
+ | | ||
+ | void fun(B& b); | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | A differenza della relazione di // | ||
+ | Nel file sorgente che implementa la classe invece si deve conoscere anche la dimensione dell' | ||
+ | |||
+ | ===== Esempio ===== | ||
+ | Esempio di codice che fa uso dell' | ||
+ | |||
+ | |||
+ | |||
+ | ===== Esercizio ===== | ||
+ | ==== molti a molti ==== | ||
+ | Sviluppare due classi che rappresentino il concetto di auto e di persona, nel senso che: | ||
+ | * ogni persona possiede più auto | ||
+ | * ogni auto appartiene a più persone | ||
+ | La presenza di DUE REGOLE indica un doppio orientamento: | ||
+ | |||
+ | Tra due classi ci possono essere anche più relazioni (ad esempio l'auto può " | ||
+ | |||
+ | Altro esempio molti a molti con i conti correnti e i correntisti... | ||
+ | Il membro " | ||
+ | |||
+ | === Classi associative === | ||
+ | |||
+ | Se la relazione di associazione ha degli " | ||
+ | |||
+ | ==== Uno a molti ==== | ||
+ | |||
+ | * ogni classe possiede uno o più studenti | ||
+ | * ogni studente è contenuto in una classe | ||
+ | |||
+ | |||
+ | |||
+ | ====== Generalizzazione ====== | ||
+ | {{: | ||
+ | * è quasi la stessa cosa dell' | ||
+ | * ha il simbolo della linea continua che termina con un triangolo | ||
+ | * ha UN SOLO verso e quindi una sola regola (vedi esempio) | ||
+ | |||
+ | ===== Principio di sostituzione ===== | ||
+ | Un oggetto della classe derivata implementa sia il modello della classe base che della classe derivata. | ||
+ | |||
+ | ===== Come si realizza? ===== | ||
+ | Si definisce la classe A come classe // | ||
+ | < | ||
+ | Class B | ||
+ | { | ||
+ | //etc. | ||
+ | }; | ||
+ | |||
+ | class A : public B | ||
+ | { | ||
+ | //etc. | ||
+ | }; | ||
+ | </ | ||
+ | In questo modo la classe A avrà, oltre ai propri membri, anche quelli ereditati da B. | ||
+ | |||
+ | Rispetto alla relazione di Aggregazione (o di Associazione), | ||
+ | |||
+ | Questo può essere utile quando ...? | ||
+ | ===== Esempio ===== | ||
+ | {{: | ||
+ | La relazione si riconosce quando nelle regole si può leggere: | ||
+ | **Ogni oggetto-derivato è un (//is a//) oggetto-base** (non viceversa). | ||
+ | Ogni automobile è un autoveicolo, | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Realizzazione ====== | ||
+ | {{: | ||
+ | |||
+ | * si rapprensenta con una linea tratteggiata che termina con un triangolo. | ||
+ | ===== Descrizione ===== | ||
+ | |||
+ | Si tratta di un caso particolare della generalizzazione ([[appunti3s: | ||
+ | |||
+ | Le classi astratte non vengono usate per instanziare oggetti ma per progettare un metodo di generazione del codice... | ||
+ | |||
+ | ===== Esempio ===== | ||
+ | |||
+ | vedi esempio [[appunti3s: | ||
+ | |||
+ | in realtà non esistono oggetti autoveicoli che hanno una targa, un proprietario, | ||