Aggregazione e composizione [chiuso]


89

Ho avuto difficoltà a capire la differenza tra composizione e aggregazione in UML. Qualcuno può offrirmi un buon confronto e contrasto tra loro? Mi piacerebbe anche imparare a riconoscere la differenza tra loro nel codice e / o vedere un breve esempio di software / codice.

Modifica: parte del motivo per cui lo chiedo è a causa di un'attività di documentazione inversa che stiamo svolgendo al lavoro. Abbiamo scritto il codice, ma dobbiamo tornare indietro e creare diagrammi di classe per il codice. Vorremmo solo catturare correttamente le associazioni.



Per favore, controlla un esempio basato sul codice su: stackoverflow.com/questions/731802/…
Almir Campos

UML 2.5 ha chiarito la differenza. Vedi il riquadro a p. 110. Quindi voto per riaprire questo.
qwerty_so

No, UML 2.5 non ha chiarito la definizione di composizione, piuttosto è rimasto ambiguo al riguardo, poiché dicono anche "Un oggetto parziale può essere rimosso da un oggetto composito prima che l'oggetto composito venga eliminato, e quindi non essere eliminato come parte di l'oggetto composto. " Vedi la mia risposta di seguito ( stackoverflow.com/questions/734891/… ) dove ho cercato di chiarire il significato della composizione. Per favore, vota la mia risposta per mostrare che in SO, la risposta corretta alla fine vince :-) [o sottovaluta tutte le risposte errate]
Gerd Wagner

Risposte:


90

La distinzione tra aggregazione e composizione dipende dal contesto.

Prendiamo l'esempio dell'auto menzionato in un'altra risposta - sì, è vero che uno scarico per auto può stare "da solo", quindi potrebbe non essere in composizione con un'auto - ma dipende dall'applicazione. Se crei un'applicazione che ha effettivamente a che fare con gli scarichi delle auto indipendenti (un'applicazione per la gestione di un'officina?), L'aggregazione sarebbe la tua scelta. Ma se questo è un semplice gioco di corse e lo scarico della macchina serve solo come parte di un'auto, beh, la composizione andrebbe benissimo.

Scacchiera? Stesso problema. Un pezzo degli scacchi non esiste senza una scacchiera solo in determinate applicazioni. In altri (come quello di un produttore di giocattoli), un pezzo degli scacchi non può sicuramente essere composto in una scacchiera.

Le cose peggiorano ancora quando si tenta di mappare la composizione / aggregazione sul proprio linguaggio di programmazione preferito. In alcune lingue, la differenza può essere più facile da notare ("per riferimento" vs. "per valore", quando le cose sono semplici) ma in altre potrebbe non esistere affatto.

E un'ultima parola di consiglio? Non perdere troppo tempo su questo problema. Non ne vale la pena. La distinzione è poco utile in pratica (anche se hai una "composizione" completamente chiara, potresti comunque volerla implementare come aggregazione per motivi tecnici, ad esempio la memorizzazione nella cache).


1
Ho detto scacchi quadrati piuttosto che pezzi degli scacchi, ma tutti i punti validi.
David M,

2
Sono decisamente in discussione con la mentalità "Non ne vale la pena". Se non pensi a chi "possiede" un oggetto ed è responsabile della sua durata, otterrai un codice molto scadente relativo all'oggetto CRUD, in particolare la pulizia, con i puntatori Null che volano in giro mentre le gerarchie degli oggetti vengono lasciate in cattive condizioni.
Chris Kessel,

9
Sì, non dovresti sprecare troppo tempo su questo problema: UML è un linguaggio OOA / OOD; L'aggregazione / composizione è di solito una decisione che è meglio rimandare all'OOP. Se provi a inserire troppi dettagli nei tuoi modelli UML, rischi la paralisi dell'analisi.
scimpanzé

13
+1 per "non perdere troppo tempo su questo". Questo è quello che avevo bisogno di sentire!
Ronnie

8
"non perdere troppo tempo su questo" Perché gli intervistatori non lo capiscono?
titogeo

96

Come regola generale: inserisci qui la descrizione dell'immagine

class Person {
    private Heart heart;
    private List<Hand> hands;
}

class City {
    private List<Tree> trees;
    private List<Car> cars
}

Nella composizione (Persona, Cuore, Mano), i "suboggetti" (Cuore, Mano) verranno distrutti non appena la Persona viene distrutta.

In aggregazione (Città, Albero, Auto) i "sottooggetti" (Albero, Auto) NON verranno distrutti quando la Città viene distrutta.

La linea di fondo è che la composizione sottolinea l'esistenza reciproca e, nell'aggregazione, questa proprietà NON è richiesta.


1
esistenza reciproca, buona B-)
jxramos

Apprezzo il tuo impegno. Un'ottima spiegazione e qualsiasi profano può capirlo.
Ravindran Kanniah

La spiegazione più semplice e migliore che ho trovato.
Akash Raghav

migliore spiegazione :)
Xiabili

UML 2.5 ha chiarito la differenza. Vedi il riquadro a p. 110. Quindi la tua risposta è sbagliata ora,
qwerty_so

51

Composizione e aggregazione sono tipi di associazioni. Sono molto strettamente correlati e in termini di programmazione non sembra esserci molta differenza tra i due. Cercherò di spiegare la differenza tra questi due esempi di codice Java

Aggregazione : l'oggetto esiste all'esterno dell'altro, viene creato all'esterno, quindi viene passato come argomento (ad esempio) al costruttore. Es: persone - auto. L'auto viene creata in un contesto diverso e poi diventa una proprietà della persona.

// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer(HttpListener listener, RequestProcessor processor) {
    this.listener = listener;
    this.processor = processor;
  }
}

Composizione : L'oggetto esiste solo, o ha senso solo dentro l'altro, come parte dell'altro. Es: Persone - cuore. Non crei un cuore e poi lo passi a una persona. Invece, il cuore viene creato quando viene creato l'umano.

// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer() {
    this.listener = new HttpListener(80);
    this.processor = new RequestProcessor(“/www/root”);
  }
}

Spiegato qui con un esempio di differenza tra aggregazione e composizione


5
Una delle migliori risposte finora. Neat :)
Rohit Singh

6
Il miglior esempio di codice Java per mostrare quando un oggetto può esistere con (composizione) o senza (aggregazione) altri oggetti.
Michał Dobi Dobrzański,

per favore, voglio sapere se dovremmo usare la finale per la composizione o no?
Outreagous ONE

36

La composizione implica che gli oggetti figli condividano una durata di vita con il genitore. L'aggregazione no. Ad esempio, una scacchiera è composta da caselle degli scacchi: le caselle degli scacchi non esistono realmente senza la scacchiera. Tuttavia, un'auto è un'aggregazione di parti: uno scarico di un'auto è ancora uno scarico di un'auto se non fa parte di un'auto in quel momento.


18

L'esempio che ho imparato sono le dita sulla mano. La tua mano è composta da dita. Li possiede. Se la mano muore, le dita muoiono. Non puoi "aggregare" le dita. Non puoi semplicemente prendere delle dita extra e attaccarle e staccarle dalla tua mano a piacimento.

Il valore qui, dal punto di vista del design, è spesso correlato alla durata di vita dell'oggetto, come ha detto un altro poster. Supponi di avere un cliente e loro hanno un account. Quell'account è un oggetto "composto" del cliente (almeno, nella maggior parte dei contesti a cui riesco a pensare). Se elimini il cliente, l'account non ha alcun valore di per sé, quindi verrà eliminato anche lui. Il contrario è spesso vero per la creazione di oggetti. Poiché un account ha significato solo nel contesto di un cliente, la creazione dell'account dovrebbe avvenire come parte della creazione del cliente (o, se lo fai pigramente, sarebbe parte di una transazione del cliente).

È utile nella progettazione pensare a quali oggetti possiedono (compongono) altri oggetti rispetto a quelli che fanno riferimento (aggregano) ad altri oggetti. Può aiutare a determinare dove risiede la responsabilità per la creazione / pulizia / aggiornamenti degli oggetti.

Per quanto riguarda il codice, spesso è difficile da dire. Quasi tutto nel codice è un riferimento a un oggetto, quindi potrebbe non essere ovvio se l'oggetto a cui si fa riferimento è composto (di proprietà) o aggregato.


15

È sorprendente quanta confusione esista sulla distinzione tra la parte-tutto - aggregazione e composizione dei concetti di associazione . Il problema principale è il malinteso diffuso (anche tra sviluppatori di software esperti e tra gli autori di UML) che il concetto di composizione implichi una dipendenza del ciclo di vita tra il tutto e le sue parti tale che le parti non possono esistere senza il tutto. Ma questo punto di vista ignora il fatto che ci sono anche casi di associazioni parte-tutto con parti non condivisibili in cui le parti possono essere staccate e sopravvivere alla distruzione del tutto.

Nel documento di specifica UML, la definizione del termine "composizione" ha sempre implicato parti non condivisibili, ma non è stato chiaro quale sia la caratteristica che definisce la "composizione" e quale sia semplicemente una caratteristica opzionale. Anche nella nuova versione (a partire dal 2015), UML 2.5, dopo aver tentato di migliorare la definizione del termine "composizione", rimane ancora ambiguo e non fornisce alcuna guida su come modellare associazioni parte-tutto con non- parti condivisibili in cui le parti possono essere staccate e sopravvivere alla distruzione del tutto, a differenza del caso in cui le parti non possono essere staccate e vengono distrutte insieme al tutto. Dicono

Se un oggetto composto viene eliminato, tutte le sue istanze di parte che sono oggetti vengono eliminate con esso.

Ma allo stesso tempo dicono anche

Un oggetto parte può essere rimosso da un oggetto composito prima che l'oggetto composito venga eliminato e quindi non può essere eliminato come parte dell'oggetto composito.

Questa confusione indica un'incompletezza della definizione UML, che non tiene conto delle dipendenze del ciclo di vita tra componenti e compositi. È quindi importante capire come la definizione UML può essere migliorata introducendo uno stereotipo UML per composizioni << inseparabili >> in cui i componenti non possono essere staccati dal loro composito e, quindi, devono essere distrutti ogni volta che il loro composito viene distrutto.

1) Composizione

Come ha spiegato Martin Fowler , il problema principale per caratterizzare la composizione è che "un oggetto può essere solo la parte di una relazione di composizione". Ciò è spiegato anche nell'eccellente post sul blog UML Composizione vs Aggregazione vs Associazione di Geert Bellekens. Oltre a questa caratteristica distintiva di una composizione (avere parti esclusive o non condivisibili ), una composizione può anche avere una dipendenza dal ciclo di vita tra il composito e i suoi componenti. In effetti, esistono due tipi di tali dipendenze:

  1. Ogni volta che un componente deve essere sempre attaccato a un composto, o, in altre parole, quando ha un composto obbligatorio , come espresso dalla molteplicità "esattamente uno" sul lato composito della linea di composizione, allora deve essere riutilizzato in (o ricollegati a) un altro composito, o distrutto, quando il suo attuale composito viene distrutto. Ciò è esemplificato dalla composizione tra Persone Heart, mostrata nel diagramma sottostante. Un cuore viene distrutto o trapiantato su un'altra persona, quando il suo proprietario è morto.
  2. Ogni volta che un componente non può essere staccato dal suo composto, o, in altre parole, quando è inseparabile , allora, e solo allora, il componente deve essere distrutto, quando il suo composto viene distrutto. Un esempio di una tale composizione con parti inseparabili è la composizione tra Persone Brain.

inserisci qui la descrizione dell'immagine

In sintesi, le dipendenze del ciclo di vita si applicano solo a casi specifici di composizione, ma non in generale, non sono quindi una caratteristica determinante.

La specifica UML afferma: "Una parte può essere rimossa da un'istanza composita prima che l'istanza composita venga eliminata e quindi non essere eliminata come parte dell'istanza composita". Nell'esempio di Car- Enginecomposizione, come mostrato nello schema seguente, è chiaramente il caso che il motore può essere staccato dalla macchina prima che la macchina è distrutta, nel qual caso il motore non viene distrutta e può essere riutilizzato. Ciò è implicito dallo zero o da una molteplicità sul lato composito della linea di composizione.

inserisci qui la descrizione dell'immagine

La molteplicità dell'estremità dell'associazione di una composizione sul lato composito è 1 o 0..1, a seconda del fatto che i componenti abbiano o meno un composto obbligatorio (deve essere collegato a un composto). Se i componenti sono inseparabili , ciò implica che hanno un composto obbligatorio.

2) Aggregazione

Un'aggregazione è un'altra forma speciale di associazione con il significato inteso di una relazione parte-tutto, in cui le parti di un tutto possono essere condivise con altri interi. Ad esempio, possiamo modellare un'aggregazione tra le classi DegreePrograme Course, come mostrato nel diagramma seguente, poiché un corso fa parte di un corso di laurea e un corso può essere condiviso tra due o più corsi di laurea (ad esempio una laurea in ingegneria potrebbe condividere un C corso di programmazione con laurea in informatica).

inserisci qui la descrizione dell'immagine

Tuttavia, il concetto di un'aggregazione con parti condivisibili non significa molto, in realtà, quindi non ha implicazioni sull'implementazione e molti sviluppatori quindi preferiscono non utilizzare il diamante bianco nei loro diagrammi di classe, ma modellano solo una semplice associazione anziché. La specifica UML dice: "La semantica precisa dell'aggregazione condivisa varia in base all'area di applicazione e al modellatore".

La molteplicità dell'associazione di un'aggregazione che termina al lato intero può essere un numero qualsiasi (*) perché una parte può appartenere a, o essere condivisa tra, un numero qualsiasi di interi.


2
La composizione non è strettamente correlata al ciclo di vita, ma nella maggior parte dei problemi del mondo reale il ciclo di vita è una motivazione primaria per decidere se comporre o aggregare. Mi sono difeso nella mia risposta, dicendo che il ciclo di vita è "spesso" correlato piuttosto che sempre correlato. È bene notare che il ciclo di vita non è richiesto, ma affermare che la vista è un "problema principale" e sbagliato (in un bel carattere in grassetto) mi sembra inutile e sminuisce dal sottolineare le considerazioni sull'uso pratico.
Chris Kessel

Sono fortemente in disaccordo. Le considerazioni sul ciclo di vita non possono essere un "motivatore primario del fatto che tu debba comporre o aggregare", dal momento che in molti casi le hai di associazioni indipendentemente dal fatto se rappresentano qualsiasi tipo di relazione parziale-intera (aggregazione o composizione). Ogni volta che un'associazione ha un'estremità con una molteplicità di limite inferiore maggiore di 0, corrispondente a una proprietà di riferimento obbligatoria, si otterrà una dipendenza del ciclo di vita.
Gerd Wagner

9

In termini di codice, la composizione di solito suggerisce che l'oggetto contenitore è responsabile della creazione di istanze del componente * e l'oggetto contenitore contiene gli unici riferimenti di lunga durata ad esso. Quindi, se l'oggetto genitore viene de-referenziato e sottoposto a garbage collection, così farà il bambino.

quindi questo codice ...

Class Order
   private Collection<LineItem> items;
   ...
   void addOrderLine(Item sku, int quantity){
         items.add(new LineItem(sku, quantity));
   }
}

suggerisce che LineItem è un componente di Order - LineItems non ha esistenza al di fuori del loro ordine contenitore. Ma gli oggetti Item non vengono costruiti nell'ordine: vengono passati secondo necessità e continuano a esistere, anche se il negozio non ha ordini. quindi sono associati, piuttosto che componenti.

* nb il contenitore è responsabile dell'installazione del componente, ma in realtà potrebbe non chiamare new ... () stesso - essendo java, di solito ci sono una o due factory da passare attraverso!


0

Le illustrazioni concettuali fornite in altre risposte sono utili, ma vorrei condividere un altro punto che ho trovato utile.

Ho ottenuto un po 'di distanza da UML per la generazione di codice, per il codice sorgente o DDL per il database relazionale. Lì, ho usato la composizione per indicare che una tabella ha una chiave esterna non annullabile (nel database) e un oggetto "genitore" (e spesso "finale") non annullabile, nel mio codice. Uso l'aggregazione quando intendo che un record o un oggetto possa esistere come "orfano", non collegato a nessun oggetto genitore, o essere "adottato" da un oggetto genitore diverso.

In altre parole, ho usato la notazione della composizione come scorciatoia per implicare alcuni vincoli aggiuntivi che potrebbero essere necessari durante la scrittura del codice per il modello.


0

L'esempio che mi piace: Composizione: l' acqua è una parte di uno stagno. (Lo stagno è una composizione di acqua.) Aggregazione: lo stagno ha anatre e pesci (lo stagno aggrega anatre e pesci)

Come puoi vedere, ho messo in grassetto "part-of" e "has", poiché queste 2 frasi possono tipicamente indicare che tipo di connessione esiste tra le classi.

Ma come sottolineato da altri, molte volte se la connessione è una composizione o un'aggregazione dipende dall'applicazione.


Ma parte di e ha i termini a volte confonde. Ad esempio, una classe Persona "ha" nome, quindi mostra come Persona ha una relazione di aggregazione con nome. In effetti, è relazione di composizione. Perché? Quando l'oggetto Person viene distrutto, lo stesso dovrebbe essere il nome. E il termine "il nome fa parte della persona" non suona naturale.
Asif Shahzad

0

È così difficile fare una differenza tra relazione aggregata e relazione composita, ma prenderò alcuni esempi, abbiamo una casa e stanze, qui abbiamo una relazione composita, la stanza è una parte della casa e la vita della stanza è iniziata con la vita di casa e Finirà quando la vita di casa finirà, la stanza è una parte della casa, parliamo di composizione, come paese e capitale, libro e pagine. Per un esempio di relazione aggregata, prendi squadra e giocatori, il giocatore può esistere senza squadra e la squadra è un gruppo di giocatori e la vita del giocatore può iniziare prima di quella della squadra, se parliamo di programmazione, possiamo creare giocatori e dopo creeremo squadra, ma per la composizione no, creiamo stanze all'interno della casa. Composizione ----> composito | comporre. Aggregazione -------> gruppo | elemento


0

Definiamo i termini. L'aggregazione è un metaterm nello standard UML e significa SIA composizione e aggregazione condivisa, semplicemente denominata condivisa . Spesso viene chiamato in modo errato "aggregazione". È MALE, perché anche la composizione è un'aggregazione. A quanto ho capito, intendi "condiviso".

Più lontano dallo standard UML:

composito - Indica che la proprietà è aggregata in modo composito, ovvero l'oggetto composto è responsabile dell'esistenza e della memorizzazione degli oggetti composti (parti).

Quindi, l'associazione University to cathedras è una composizione, perché la cathedra non esiste fuori dall'università (IMHO)

La semantica precisa dell'aggregazione condivisa varia in base all'area di applicazione e al modellatore.

Cioè, tutte le altre associazioni possono essere disegnate come aggregazioni condivise, se segui solo alcuni principi tuoi o di qualcun altro. Guarda anche qui .


0

Considera parti del corpo umano come reni, fegato, cervello. Se proviamo a mappare qui il concetto di composizione e aggregazione, sarebbe come:

Prima dell'avvento del trapianto di parti del corpo come quello del rene e del fegato, queste due parti del corpo erano in composizione con il corpo umano e non possono esistere isolamento con il corpo umano.

Ma dopo l'avvento del trapianto di parti del corpo, possono essere trapiantate in un altro corpo umano, quindi queste parti sono in aggregazione con il corpo umano poiché la loro esistenza in isolamento con il corpo umano è ora possibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.