Notazioni del diagramma delle classi UML: differenze tra associazione, aggregazione e composizione

35

Sono confuso su alcune delle notazioni dei diagrammi delle classi UML.

Abbastanza sicuro di sapere cosa significa Associazione . Qualsiasi relazione tra istanze di due classi, in cui un'istanza di una classe deve conoscere un'istanza della seconda classe per poter eseguire il proprio lavoro, è una relazione di associazione. Un'associazione spesso indica che la classe A ha un riferimento (campo) a un'istanza di classe B.

Tuttavia, ho difficoltà a capire che cosa significano le frecce Aggregazione e Composizione . Parte della mia confusione è stata causata dall'incontro con diverse definizioni di queste notazioni.

Due definizioni della notazione Aggregazione :

Definizione 1: Una notazione di aggregazione tra due classi è adatta ogni volta che un'istanza di classe A contiene una raccolta di istanze di classe B (ad esempio una lista, una matrice, qualunque sia ).

Definizione 2: Un legame di aggregazione tra due classi è adatto se un'istanza della classe A contiene un riferimento a un'istanza di classe B, e l'istanza B dipende dal ciclo di vita di l'istanza A. Significato: quando l'istanza della classe A viene cancellata, anche l'istanza della classe B. L'istanza della classe B è interamente contenuta dall'istanza della classe A, come contrario all'istanza della classe A che possiede semplicemente un riferimento all'istanza della classe B (che è un'associazione regolare).

Riguardo a cosa significa la notazione di composizione e in che modo differisce dalla notazione di aggregazione, non sono sicuro.

Per favore chiarisci le definizioni e aiutami a capire. Esempi concreti sarebbero i benvenuti.

    
posta Aviv Cohn 08.04.2014 - 23:57
fonte

4 risposte

29

I tre collegamenti Associazione, Aggregazione e Composizione formano una sorta di scala su quanto due classi sono strettamente correlate tra loro.

A un'estremità della scala, c'è l'Associazione, in cui gli oggetti delle due classi possono conoscersi l'un l'altro, ma non si influenzano a vicenda. Gli oggetti possono esistere indipendentemente e quale oggetto di classe A sa quali oggetti di classe B possono variare nel tempo.

Dall'altra parte della scala, c'è la composizione. La composizione rappresenta una parte - una relazione intera tale che la classe B è parte integrante della classe A. Questa relazione viene in genere utilizzata se gli oggetti di classe A non possono esistere logicamente senza avere un oggetto di classe B.

La relazione di aggregazione è da qualche parte tra questi due estremi, ma nessuno sembra concordare esattamente dove, quindi non esiste anche una definizione universalmente condivisa di cosa significhi un'aggregazione. In questo senso, entrambe le definizioni che hai trovato sono corrette e se chiedi a 10 persone, rischi di ottenere 11 definizioni diverse.

    
risposta data 09.04.2014 - 09:02
fonte
9

La composizione è quando object A contiene object B e object A è anche responsabile della creazione di object B .

Relazione di composizione

Abbiamo una classe A che verrà utilizzata dalla classe B.

final class A
{
}

Ci sono diverse opzioni su come può apparire la composizione.

Composizione di inizializzazione diretta:

final class B
{
    private $a = new A();
}

Composizione di inizializzazione del costruttore

final class B
{
    private $a;

    public function __construct()
    {
        $this->a = new A();
    }
}

Composizione di inizializzazione pigra

final class B
{
    private $a = null;

    public function useA()
    {
        if ($this->a === null) {
            $this->a = new A();
        }

        /* Use $this->a */
    }
}

Si vede che crea una stretta relazione tra le classi A e B . La classe B semplicemente non può esistere senza A . Si tratta di un'enorme violazione del principio dell'iniezione dipendente , che dice:

A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. The service is made part of the client's state. Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

La composizione a volte ha senso, come chiamare new DateTime in php o new std::vector<int> in C ++. Ma il più delle volte, è un avvertimento, che la progettazione del codice è sbagliata.

In un caso, in cui class A sarebbe un oggetto speciale utilizzato per la memorizzazione nella cache, class B verrebbe sempre memorizzato nella cache utilizzando l'implementazione di class A e non avresti alcun controllo per modificarlo dinamicamente, che è male.

Inoltre, se hai usato la composizione di inizializzazione pigra , significa che avresti un object B funzionante, chiamato il metodo useA() e la creazione di object A fallirebbe, il tuo object B è improvvisamente inutile.

L'aggregazione, d'altra parte, è una modalità di relazione, che segue il principio DI . object B deve usare object A , quindi dovresti passare l'istanza già creata di object A a object B , e se la creazione di object A fallisce, nulla verrebbe passato in primo luogo.

In breve, Aggregation è la rappresentazione UML per il principio dell'iniezione di dipendenza , che si tratti di un'iniezione del costruttore, dell'iniezione del setter o dell'iniezione della proprietà pubblica.

Queste sono tutte le aggregazioni

L'iniezione del costruttore più stretta ( object B non può esistere senza object A ).

final class B
{
    private $a;

    public function __construct(A $a)
    {
        $this->a = $a;
    }
}

Looser (puoi utilizzare o meno object A all'interno di object B , ma se lo fai, dovresti probabilmente impostarlo prima).

Via setter:

final class B
{
    private $a;

    public function setA(A $a)
    {
        $this->a = $a;
    }
}

Tramite proprietà pubblica:

final class B
{
    public $a;
}

Non c'è un ottimo modo per giustificare l'utilizzo di Aggregation su Composition, se tutto ciò che si sta usando è una concreta implementazione di classi, ma una volta che si inizia a iniettare interfacce o in caso di classi astratte in C ++, improvvisamente l'Aggregation sarà il unico modo per soddisfare il tuo contratto.

    
risposta data 23.09.2015 - 17:22
fonte
1

Inoltre un estratto dello standard UML corrente:

11.5.4 Associazioni - Semantica - Notazione

[...] A binary Association may have one end with aggregation = AggregationKind::shared or aggregation = AggregationKind::composite. When one end has aggregation = AggregationKind::shared a hollow diamond is added as a terminal adornment at the end of the Association line opposite the end marked with aggregation = AggregationKind::shared. The diamond shall be noticeably smaller than the diamond notation for Associations. An Association with aggregation = AggregationKind::composite likewise has a diamond at the corresponding end, but differs in having the diamond filled in. […]

9.5.4 Classificazione - Proprietà - Notazione

[…] Sometimes a Property is used to model circumstances in which one instance is used to group together a set of instances; this is called aggregation. To represent such circumstances, a Property has an aggregation property, of type AggregationKind; the instance representing the whole group is classified by the owner of the Property, and the instances representing the grouped individuals are classified by the type of the Property. AggregationKind is an enumeration with the following literal values:

  • none: Indicates that the Property has no aggregation semantics.
  • Shared: Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.
  • Composite: Indicates that the Property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (see the definition of parts in 11.2.3). Composite aggregation is a strong form of aggregation that requires a part object be included in at most one composite object at a time. If a composite object is deleted, all of its part instances that are objects are deleted with it.

[…]

    
risposta data 23.09.2015 - 16:45
fonte
0

Ho già pubblicato un risposta su Stackoverflow .

Fondamentalmente, un'aggregazione è più strong di una semplice associazione ma gli oggetti aggregati possono continuare a "vivere" l'uno senza l'altro come con una semplice associazione.

Una composizione è persino più strong di un'aggregazione perché la classe aggregata non può essere aggregata da altre classi. La sua "vita" dipende dal contenitore.

    
risposta data 09.04.2014 - 10:00
fonte

Leggi altre domande sui tag