Progettazione del Software, Laurea in Ingegneria Gestionale
Università degli Studi di Roma “La Sapienza”
Facoltà di Ingegneria – Corso di Laurea in Ingegneria Gestionale
Corso di Progettazione del Software
Proff. Toni Mancini e Monica Scannapieco
Dipartimento di Informatica e Sistemistica
Università di Roma “La Sapienza”
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola
versione del February 26, 2008
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 1/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Modifiche rispetto alle precedenti versioni
Modificata slide n. 25 (Realizz. di assoc. di molt. 0..*
(cont.)) aggiungendo la versione di getLinkAssoc() che utilizza le versioni generics
delle interfacce e delle classi del Java Collection Framework.
Rispetto alla versione del 6 Marzo 2007
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 2/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni a resp. singola
Consideriamo il caso più semplice, in cui:
– l’associazione è binaria, di molteplicità 0..1 da C a D
– Dal diagramma delle classi realizzativo si evince che la classe C è l’unica ad avere
responsabilità sull’associazione assoc (cioè dobbiamo realizzare un “solo verso” della
associazione)
– Nel diagramma realizzativo abbiamo convertito l’associazione in aggregazione, dato
che assoc non ha attributi.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 3/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni a resp. singola (cont.)
La realizzazione dell’associazione è simile a quella di un attributo. Infatti, oltre a quanto
stabilito per gli attributi e le operazioni, per ogni associazione assoc del tipo mostrato in
figura, aggiungiamo alla class Java C:
– un campo dato assoc di tipo D private (o protected) che rappresenta, per ogni
oggetto x della classe C, l’eventuale oggetto della classe D connesso ad x tramite
l’associazione assoc.
Per un oggetto x della class C, il campo assoc sarà pari a null se x non partecipa ad
alcun link di associazione assoc;
– Un metodo “public D getAssoc() { return assoc; }” che ritorna, per ogni
oggetto x della classe C, l’oggetto della classe D connesso a x tramite l’associazione
assoc (la funzione restituisce null se x non partecipa ad alcuna istanza di assoc);
– un metodo “public void setAssoc(D d) { assoc = d; }”, che, quando
invocato sull’oggetto x della class C, implementa la creazione del link hx, di
dell’associazione assoc, eliminando l’eventuale link già presente che coinvolge x.
Utilizzando tale metodo con l’argomento pari a null, il cliente può cancellare
l’eventuale link esistente di associazione assoc che coinvolge x.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 4/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio
public class Persona {
...
private Azienda lavoraIn = null;
public Azienda getLavoraIn() { return lavoraIn; }
public void setLavoraIn(Azienda a) { lavoraIn = a; }
...
}
La class Azienda non conterrà alcun attributo o metodo relativo alla gestione
dell’associazione assoc, dato che la corrispondente classe UML Azienda non ha
responsabilità su di essa.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 5/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esercizio
– Estendere la classe Azienda aggiungendo l’operazione dimensione() : String che
ritorna una stringa tra “piccola”, “media”, oppure “grande”, a seconda che il suo
capitale sociale sia ≤ 50, tra 50 e 250, o maggiore di 250.
– Scrivere le specifiche concettuale (relativa alla fase di Analisi) e realizzativa (relativa
alla fase di Progetto) della classe Azienda che contenga la specifica di tale operazione.
– Scrivere inoltre le specifiche concettuale e realizzativa della operazione
redditoMedioInGrandiAziende() dello use case Analisi Statistica, che, preso in input un
insieme S di persone, calcola il reddito medio delle persone di S che lavorano in
grandi aziende.
– Scrivere la class Java Azienda con la definizione del metodo dimensione().
– Scrivere la class Java che realizza lo use case.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 6/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Realizzazione di associazioni riflessive
Quanto detto vale anche per il caso in cui l’associazione coinvolga più volte la stessa classe.
In questo caso il concetto di responsabilità si attribuisce ai ruoli, piuttosto che alla classe.
Supponiamo che la classe Azienda abbia la responsabilità su holding, solo nel ruolo
controllata.
public class Azienda {
...
// il nome del campo e’ uguale al ruolo
private Azienda controllante = null;
...
public Azienda getControllante() { return controllante; }
public void setControllante(Azienda a) { controllante = a; }
...
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 7/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni {0,1} con attributi
In questo caso dobbiamo mantenere una rappresentazione esplicita dei link per per
gestire opportunamente gli attributi dell’associazione assoc.
A tale scopo si introduce un’ulteriore class Java TipoLinkAssoc le cui istanze
rappresentano link dell’associazione assoc, ovvero coppie hc : C, d : Di con un valore per
ogni attributo di associazione (attr in questo caso).
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 8/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Assoc. {0,1} con attributi (cont.)
La classe Java TipoLinkAsssoc:
– Sarà definita public e final, perché non vogliamo che i clienti possano
sottoclassarla;
– Avrà un campo dato private final per ogni oggetto coinvolto nel link;
private final C c;
private final D d;
– Avrà un campo dato private per ogni attributo di associazione.
– Avrà un costruttore public che prende in input gli oggetti coinvolti nel link ed i valori
per gli attributi, e crea un oggetto che rappresenta un link dell’associazione assoc.
– Avrà i metodi public C getC() e public D getD() che ritornano il riferimento
agli oggetti coinvolti nel link (attenzione: non avrà metodi setC() e setD(), perché
non vogliamo che il cliente possa cambiare gli oggetti coinvolti nel link: a parte il valore
degli attributi, i link sono oggetti immutabili!);
– Avrà ulteriori metodi per gestire gli attributi di associazione, analogamente agli attributi
delle classi (ad es. un metodo get...() e un metodo set...() per gli attributi
mutabili).
– Ridefinirà i metodi equals() e hashCode() ereditati da Object allo scopo di
rispettare la semantica di UML, secondo la quale due link sono uguali (e quindi i
corrispondenti oggetti di classe TipoLinkAssoc devono essere equal) se e solo se
coinvolgono la stessa coppia di oggetti, indipendentemente dal valore degli attributi di
associazione.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 9/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Class Java TipoLinkAssoc
La class Java TipoLinkAssoc relativa all’associazione assoc della figura precedente, avrà
quindi la seguente forma:
public final class TipoLinkAssoc {
// Oggetti coinvolti nel link:
private final C c;
private final D d;
// Attributi di associazione:
private T attr; // ’final’ se immutabile e noto alla nascita
// Costruttore:
public TipoLinkAssoc(C cc, D dd, T a) throws EccezionePrecondizioni {
if (cc == null || dd == null) throw new EccezionePrecondizioni(
"Gli oggetti linkati non possono essere null");
if (/* verifica eventuali cond. di ammissibilita’ per ’a’ */) {
c = cc;
d = dd;
attr = a;
}
else throw new EccezionePrecondizioni(
"Il valore per l’attributo ’a’ non e’ legale");
}
public C getC() { return c; }
public D getD() { return d; }
...
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 10/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Class Java TipoLinkAssoc (cont.)
// Gestione attributi di associazione: come gia’ visto per le classi
public T getAttr() {
return attr; // se T non permette side-effect
// altrimenti: return (T)attr.clone();
}
// Se attr e’ mutabile
public void setAttr(T a) throws EccezionePrecondizioni {
...
}
public boolean equals(Object o) { // Ridefinizione di Object.equals()
if (o == null) return false;
if (!o.getClass().equals(getClass())) return false;
TipoLinkAssoc l = (TipoLinkAssoc)o;
return c == l.c && d == l.d;
/* Attenzione: il valore degli attributi di associazione
non contribuisce al controllo dell’uguaglianza!! */
}
public int hashCode() { return c.hashCode() + d.hashCode(); }
// idem per hashCode()!
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 11/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni {0,1} con attributi (cont.)
Per quanto riguarda la class Java C (l’unica responsabile):
– Avrà un campo private TipoLinkAssoc linkAssoc (e non più di tipo D). Tale
campo sarà pari a null per un oggetto c di classe C se c non è coinvolto in alcun link
di associazione assoc.
– Avrà un metodo “public TipoLinkAssoc getLinkAssoc() { return
linkAssoc; }” (e non più public D getAssoc()”);
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 12/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni {0,1} con attributi (cont.)
– Avrà un metodo “public void inserisciLinkAssoc(TipoLinkAssoc l)” per
consentire l’inserimento di un nuovo link, nel caso sia possibile. Tale metodo segue lo
schema seguente:
public void inserisciLinkAssoc(TipoLinkAssoc l)
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (linkAssoc != null) throw
new EccezioneMolteplicita("L’oggetto ha gia’ un link");
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
if (l.getC() == this) linkAssoc = l;
else throw new EccezionePrecondizioni("Il link non coinvolge this");
}
– Avrà un metodo “public void eliminaLinkAssoc(TipoLinkAssoc l)” per
consentire l’eliminazione del link dato come argomento, nel caso esista. Tale metodo
segue lo schema seguente:
public void eliminaLinkAssoc(TipoLinkAssoc l) throws EccezionePrecondizioni {
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
if (l.equals(linkAssoc)) { linkAssoc = null; }
else throw new EccezionePrecondizioni(
"this non ha questo link");
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 13/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio
Consideriamo il seguente frammento di diagramma delle classi concettuale:
public final class TipoLinkLavora {
private final Persona persona; // Oggetti coinvolti nel link
private final Azienda azienda;
private final Data dataInizio;
// Attributo di associazione
// Costruttore:
public TipoLinkLavora(Persona p, Azienda a, Data d) throws EccezionePrecondizioni {
if (p == null || a == null) throw new EccezionePrecondizioni(
"Gli oggetti linkati non possono essere null");
if (d != null) {
persona = p;
azienda = a;
dataInizio = d;
}
else throw new EccezionePrecondizioni(
"Il valore per l’attributo dataInizio non e’ legale");
}
public Persona getPersona() { return persona; }
public Azienda getAzienda() { return azienda; }
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 14/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio (cont.)
// public final class TipoLinkLavora {
...
// Gestione attributi di associazione: come gia’ visto per le classi
public Data getDataInizio() {
return dataInizio; // se Data non permette side-effect
// altrimenti: return (Data)dataInizio.clone();
}
// dataInizio e’ immutabile: niente metodo setDataInizio().
// Ridefinizione di Object.equals()
public boolean equals(Object o) {
if (o == null) return false;
if (!o.getClass().equals(getClass())) return false;
TipoLinkLavora l = (TipoLinkLavora)o;
return persona == l.persona && azienda == l.azienda;
}
public int hashCode() {
return persona.hashCode() + azienda.hashCode();
}
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 15/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio (cont.)
Per la classe Persona, responsabile dell’associazione lavora:
public class Persona {
...
private TipoLinkLavora linkLavora = null;
...
public void inserisciLinkLavora(TipoLinkLavora l)
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (linkLavora != null) throw
new EccezioneMolteplicita("Il link gia’ esiste");
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
if (l.getPersona() == this) linkLavora = l;
else throw
new EccezionePrecondizioni("Il link non coinvolge this");
}
public void eliminaLinkLavora(TipoLinkLavora l) throws EccezionePrecondizioni {
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
if (l.equals(linkLavora)) { linkLavora = null; }
else throw new EccezionePrecondizioni(
"this non ha questo link");
}
public TipoLinkLavora getLinkLavora() { return linkLavora; }
...
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 16/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio: Possibile stato della memoria
nome
cognome
linkLavora
"Mario"
"Rossi"
nome
cognome
linkLavora
"Aldo"
"Bianchi"
null
persona
"3/2/1997"
dataInizio azienda
nome
...
"IBM"
...
Due oggetti di classe Persona, di cui uno che lavora ed uno no.
La situazione dell’esempio può essere ottenuta dal seguente frammento di codice cliente:
...
Persona mario = new Persona("Mario", "Rossi", ...);
Persona aldo = new Persona("Aldo", "Bianchi", ...);
Azienda ibm = new Azienda("IBM", ...);
try {
TipoLinkLavora l = new TipoLinkLavora(mario, ibm, new Data(3,2,1997));
mario.inserisciLinkLavora(l);
}
catch(EccezionePrecondizioni ep) {...}
catch(EccezioneMolteplicita em) {...}
...
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 17/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Osservazioni
Dal precedente codice cliente si osservi come, per inserire un link di associazione lavora tra
gli oggetti mario e ibm, il cliente deve, nell’ordine:
– Creare un oggetto di classe TipoLinkLavora:
TipoLinkLavora l = new TipoLinkLavora(mario, ibm, new Data(3,2,1997));
Il costruttore della classe TipoLinkLavora si occuperà di controllare che gli
argomenti non siano null e che il valore dell’attributo sia legale (verifica precondizioni
lato server).
– Assegnare il link appena creato all’oggetto mario:
mario.inserisciLinkLavora(l);
Il metodo inserisciLinkLavora() della classe Persona si occuperà di controllare
che:
– L’oggetto di invocazione non sia già coinvolto in un link di associazione lavora (i
vincoli di molteplicità sull’associazione sono {0..1}!)
– Il link passato per argomento non sia null;
– Il link passato per argomento si riferisca all’oggetto di invocazione this
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 18/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Osservazioni (cont.)
Si noti come tale metodologia di realizzazione influenza negativamente alcuni fattori di
qualità, in particolare porta ad un alto accoppiamento tra le classi TipoLinkAssoc e C (la
classe responsabile), perché:
– Il cliente, per assegnare un link a mario deve prima crearlo, e poi assegnarlo a mario;
– Il metodo Persona.inserisciLinkLavora() deve controllare che il link passato
per argomento si riferisca all’oggetto Persona di invocazione this, evitando di
inserire il link in caso contrario. Infatti, il cliente potrebbe tentare di assegnare il link
appena creato ad un altro oggetto di classe Persona, ad esempio scrivendo il
seguente codice:
TipoLinkLavora l = new TipoLinkLavora(mario, ibm, new Data(3,2,1997));
aldo.inserisciLinkLavora(l); // !!!
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 19/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Una metod. di realizz. di migliore qualità
Per migliorare la qualità complessiva della realizzazione, si può procedere come segue:
– Nella classe responsabile dell’associazione, C, si modifica il metodo
inserisciLinkAssoc(), cambiandone anche la segnatura. Il metodo diventa:
// Ora gli argomenti sono l’oggetto da linkare e il valore per
// gli attributi
public void inserisciLinkAssoc( D d, T attr )
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (linkAssoc != null) // this ha gia’ un link
throw new EccezioneMolteplicita("this ha gia’ un link");
TipoLinkAssoc l = new TipoLinkAssoc(this, d, attr);
// Da qui posso invocare il costruttore di TipoLinkAssoc.
// Se d == null o attr non e’ legale, il costruttore di TipoLinkAssoc
// genera un’eccezione EccezionePrecondizioni
// e questo metodo viene interrotto.
// Qui non devo fare piu’ alcun controllo!
linkAssoc = l;
}
– Il metodo eliminaLinkAssoc(TipoLink l) resta invece invariato, perché
vogliamo che il cliente espliciti, dandolo per argomento, il link da eliminare (ottenuto ad
es. mediante il metodo getLinkAssoc()).
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 20/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Una met. di real. di migl. qual. (cont.)
Tornando all’esempio dell’associazione lavora tra le classi Persona e Azienda (di cui
Persona è l’unica responsabile), il cliente, per creare un link tra mario e ibm deve
semplicemente scrivere:
Persona mario = new Persona(...);
Persona ibm = new Azienda(...);
try {
mario.inserisciLinkLavora(ibm, new Data(3,2,1997));
}
catch(EccezionePrecondizioni ep) {...}
catch(EccezioneMolteplicita em) {...}
...
Si noti come abbiamo semplificato sia la gestione da parte del cliente, sia quella da parte
della classe.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 21/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esercizio: use case
Con riferimento al diagramma delle classi che contiene le classi Persona e Azienda e
l’associazione lavora, si considerino le seguenti operazioni dello use-case Ristrutturazione
aziendale:
1. Dato un insieme P di persone, un’azienda a e una data d, si vuole modificare lo stato
del sistema in modo che tutte le persone in P siano assunte dall’azienda a a partire
dalla data d;
2. Dato un insieme P di persone, un’azienda a e due date dv e d, si vuole modificare lo
stato del sistema in modo che tutte le persone in P che lavorano in una qualsiasi
azienda diversa da a da prima di dv siano assunte dall’azienda a a partire dalla data d.
Si richiede di:
– Scrivere la specifica concettuale dello use case;
– Scrivere la specifica realizzativa dello use case;
– Realizzare lo use case in Java.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 22/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Realizz. di associazioni di molt. {0..*}
In questo caso, dobbiamo permettere alla class C di mantenere un insieme di oggetti di class
TipoLinkAssoc, per rappresentare l’insieme di link in cui i suoi oggetti sono coinvolti.
Pertanto:
– Prevediamo, come al solito, la class TipoLinkAssoc per la rappresentazione
esplicita dei link;
– La class C avrà ora il campo dato linkAssoc di tipo Set, inizializzato all’insieme
vuoto di oggetti di classe TipoLinkAssoc:
private Set linkAssoc = new InsiemeArrayOmogeneo(TipoLinkAssoc.class);
oppure
private Set<TipoLinkAssoc> linkAssoc = new HashSet<TipoLinkAssoc>();
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 23/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Realizz. di assoc. di molt. {0..*} (cont.)
– Il metodo C.inserisciLinkAssoc(D d, T attr) avrà la seguente definizione:
public void inserisciLinkAssoc( D d, T attr ) throws EccezionePrecondizioni {
TipoLinkAssoc l = new TipoLinkAssoc(this, d, attr);
linkAssoc.add(l);
}
Si noti come il link hthis, di viene aggiunto all’insieme dei link dell’oggetto di class C
this.
Inoltre, dato che il campo linkAssoc è di tipo Set, il metodo add() invocato su
linkAssoc si occuperà di evitare di inserire un link che è equal ad uno già inserito
(coincidente quindi nella coppia degli oggetti linkati, indipendentemente dal valore
degli attributi, cf. definizione del metodo TipoLinkAssoc.equals()), rispettando
quindi la semantica di UML.
– Il metodo C.eliminaLinkAssoc(TipoLinkAssoc l) avrà la seguente definizione:
public void eliminaLinkAssoc(TipoLinkAssoc l) throws EccezionePrecondizioni {
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
linkAssoc.remove(l);
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 24/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Realizz. di assoc. di molt. {0..*} (cont.)
– Infine, il metodo C.getLinkAssoc() restituirà una copia dell’insieme dei link (dato
che l’interfaccia Set permette side-effect):
public Set getLinkAssoc() {
return (Set)((InsiemeArrayOmogeneo)linkAssoc).clone();
}
oppure
public Set<TipoLinkAssoc> getLinkAssoc() {
return (Set<TipoLinkAssoc>)
((HashSet<TipoLinkAssoc>)linkAssoc).clone();
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 25/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Aggregazioni {0..*} (ass. senza attrib.)
Ovviamente, nel caso in cui l’associazione assoc non abbia attributi, possiamo, in fase di
Progetto, convertirla in aggregazione, ed evitare, in fase di Realizzazione, di mantenere una
rappresentazione esplicita dei link.
In particolare, in questo caso possiamo:
– Evitare di creare la classe TipoLinkAssoc;
– Modificare, nella classe C, la definizione dl campo dato per la rappresentazione dei
link, che ora viene inizializzato ad insieme vuoto di oggetti di classe D):
private Set<D> assoc = new HashSet<D>();
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 26/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Aggregazioni {0..*} (cont.)
– Modificare, nella classe C i metodi per l’inserimento, la rimozione, e l’interrogazione dei
link nel modo seguente:
// Non si chiama piu’ inserisciLinkAssoc()!
public void inserisciAssoc(D d) throws EccezionePrecondizioni {
if (D == null) throw
new EccezionePrecondizioni("d non puo’ essere null");
assoc.add(d);
}
public void eliminaAssoc(D d) throws EccezionePrecondizioni {
if (D == null) throw
new EccezionePrecondizioni("d non puo’ essere null");
linkAssoc.remove(d);
}
public Set<D> getAssoc() {
return (Set<D>)((HashSet<D>)assoc).clone();
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 27/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio
Consideriamo il seguente frammento di diagramma delle classi concettuale:
public final class TipoLinkHaLavorato {
private final Persona persona; // Oggetti coinvolti nel link
private final Azienda azienda;
private final Data da;
// Attributi di associazione
private final Data a;
public TipoLinkHaLavorato(Persona p, Azienda az, Data da, Data a)
throws EccezionePrecondizioni {
if (p == null || az == null) throw new EccezionePrecondizioni(
"Gli oggetti linkati non possono essere null");
if (da != null && a != null) {
persona = p;
azienda = az;
this.da = da; this.a = a;
}
else throw new EccezionePrecondizioni(
"I valori per gli attributi non sono tutti legali");
}
public Persona getPersona() { return persona; }
public Azienda getAzienda() { return azienda; }
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 28/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio (cont.)
// public final class TipoLinkHaLavorato {
...
// Gestione attributi di associazione: come gia’ visto per le classi
public Data getDa() {
return da; // se Data non permette side-effect
// altrimenti: return (Data)da.clone();
}
// ’da’ e’ immutabile: niente metodo setDa().
public Data getA() {
return a; // se Data non permette side-effect
// altrimenti: return (Data)a.clone();
}
// ’a’ e’ immutabile: niente metodo setA().
// Ridefinizione di Object.equals()
public boolean equals(Object o) {
if (o == null) return false;
if (!o.getClass().equals(getClass())) return false;
TipoLinkHaLavorato l = (TipoLinkHaLavorato)o;
return persona == l.persona && azienda == l.azienda;
}
public int hashCode() {
return persona.hashCode() + azienda.hashCode();
}
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 29/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio (cont.)
Per la classe Persona, responsabile dell’associazione haLavorato:
import java.util.*;
public class Persona {
...
private Set<TipoLinkHaLavorato> linkHaLavorato =
new HashSet<TipoLinkHaLavorato>();
...
public void inserisciLinkHaLavorato(Azienda az, Data da, Data a)
throws EccezionePrecondizioni {
linkHaLavorato.add( new TipoLinkHaLavorato(this, az, da, a) );
}
public void eliminaLinkHaLavorato(TipoLinkHaLavorato l)
throws EccezionePrecondizioni {
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
linkHaLavorato.remove(l);
}
public Set<TipoLinkHaLavorato> getLinkHaLavorato() {
return (Set<TipoLinkHaLavorato>)((HashSet<TipoLinkHaLavorato>)linkHaLavorato).clone();
}
...
} //:˜
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 30/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esempio di cliente
La seguente funzione stampa la ragione sociale di tutte le aziende per cui una certa persona
ha lavorato (si assume che la classe Azienda abbia un attributo realizzativo ragioneSociale:
String, e che quindi la class Azienda, omessa, ha un metodo public String
getRagioneSociale():
public static void stampaAziende(Persona p) {
System.out.println("La persona " + p.getNome() +
" ha lavorato nelle seguenti aziende:");
Interator<TipoLinkHaLavorato> it = p.getLinkHaLavorato().iterator();
while (it.hasNext()) {
TipoLinkHaLavorato l = it.next();
// Nota: se avessimo usato la classe InsiemeArrayOmogeneo (non generic)
// avremmo dovuto usare l’interfaccia Iterator (non generic) e
// avremmo dovuto scrivere: TipoLinkHaLavorato l = (TipoLinkHaLavorato)it.next();
System.out.println(l.getAzienda().getRagioneSociale());
}
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 31/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Esercizio: use-case
Relativamente al diagramma delle classi contenente le classi Persona, Azienda e
l’associazione haLavorato, si considerino le seguenti funzionalità, appartenenti allo use-case
AnalisiMercatoLavoro:
1. Data una persona p, si vuole conoscere qual è il periodo consecutivo più lungo nel
quale p ha lavorato per la stessa azienda.
2. Data due persone p1 e p2, si vuole conoscere se queste sono stati mai colleghi,
avendo lavorato contemporaneamente per la stessa azienda.
Si richiede di:
– Scrivere la specifica concettuale dello use-case (fase di Analisi), modificando, se
necessario, la specifica concettuale del tipo di dato Data, aggiungendo funzionalità;
– Effettuare la fase di Progetto, dando la specifica realizzativa dello use-case e della
struttura dati Data (se modificata);
– Realizzare lo use-case.
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 32/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Assoc. con molt. “n..m” (con n≥ 1 ed m>1)
In questo caso, dovremmo fare in modo che gli oggetti della class C siano sempre coinvolti in
un numero di link di associazione assoc maggiore o uguale ad n e minore o uguale ad m.
I metodi C.inserisciLinkAssoc(D d, T attr) ed
C.eliminaLinkAssoc(TipoLinkAssoc l) dovrebbero allora controllare che
l’inserimento o la cancellazione del link non porti alla violazione del vincolo “n..m”:
public void inserisciLinkAssoc(D d, T attr)
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (linkAssoc.size() >= m)
// <<------------throw new EccezioneMolteplicita("Il vincolo di moltepl. sarebbe violato!");
TipoLinkAssoc l = new TipoLinkAssoc(this, d, attr);
linkAssoc.add(l);
}
public void eliminaLinkAssoc(TipoLinkAssoc l)
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (l == null) throw
new EccezionePrecondizioni("Il link non puo’ essere null");
if (linkAssoc.size() <= n)
// <<------------throw new EccezioneMolteplicita("Il vincolo di moltepl. sarebbe violato!");
linkAssoc.remove(l);
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 33/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Assoc. con molt. “n..m” (cont.)
Tuttavia, appare chiaro come, in alcune situazioni, tale politica di gestione è inadeguata. Si
consideri, ad es., un associazione con il vincolo “3..3”. Come sarebbe possibile inserire il
primo link?
Per questo motivo, adottiamo la seguente metodologia, che semplifica di molto la gestione
dell’associazione, pur mantenendola corretta:
– Accettiamo che il cliente possa inserire ed eliminare i link incondizionatamente (come
se il vincolo fosse {0..*}). I metodi C.inserisciLinkAssoc(D d, T attr) ed
C.eliminaLinkAssoc(TipoLinkAssoc l) non effettuano alcun controllo sul
rispetto del vincolo di molteplicità.
– Sarà il metodo Set C.getLinkAssoc() che, in caso il numero di link non soddisfi il
vincolo “n..m”, genera un’eccezione, informando il cliente:
public Set<TipoLinkAssoc> getLinkAssoc() throws EccezioneMolteplicita {
if (linkAssoc.size() < n || linkAssoc.size() > m)
throw new EccezioneMolteplicita(
"Il vincolo di molteplicita’ e’ violato");
return (Set<TipoLinkAssoc>)((HashSet<TipoLinkAssoc>)linkAssoc).clone();
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 34/35
Progettazione del Software, Laurea in Ingegneria Gestionale
Associazioni con molteplicità “1..1”
La gestione di questo caso può essere effettuata in modo analogo:
– La class C ha un campo private TipoLinkAssoc linkAssoc;
– I metodi C.inserisciLinkAssoc() e C.eliminaLinkAssoc() restano invariati
rispetto al caso “0..1”:
public void inserisciLinkAssoc( D d, T attr )
throws EccezionePrecondizioni, EccezioneMolteplicita {
if (linkAssoc != null)
throw new EccezioneMolteplicita("this ha gia’ un link");
linkAssoc = new TipoLinkAssoc(this, d, attr);
}
public void eliminaLinkAssoc(TipoLinkAssoc l) throws EccezionePrecondizioni {
if (l == null) throw new EccezionePrecondizioni("Il link non puo’ essere null");
if (l.equals(linkAssoc)) { linkAssoc = null; }
else throw new EccezionePrecondizioni(
"this non ha questo link");
}
– Il metodo C.getLinkAssoc() diventa invece:
public TipoLinkAssoc getLinkAssoc()
throws EccezioneMolteplicita {
if (linkAssoc == null)
throw new EccezioneMolteplicita("Il vincolo di molteplicita’ e’ violato");
return linkAssoc;
}
T. Mancini & M. Scannapieco
S.R.3 – La fase di Realizzazione: realizzazione di associazioni a resp. singola – February 26, 2008 – p. 35/35
Scarica

La fase di Realizzazione, realizzazione di - Toni Mancini