Jaka jest różnica między skojarzeniem, agregacją a składem?


389

Jaka jest różnica między skojarzeniem, agregacją i kompozycją? Proszę wyjaśnić w zakresie realizacji.


2
To może być odrobinę przytłaczające dla początkującego, ale wee walk na piechotę przez UML 2 Superstructure spec: omg.org/docs/formal/09-02-02.pdf Sekcja 7.3.3 dla Stowarzyszenia
chickeninabiscuit

6
Powinienem również dodać, że w UML 2 nie ma takiego elementu jak Aggregation czy Composition (choć było to w UML 1.4). W UML 2 agregacja / kompozycje są implementowane jako elementy asocjacyjne z właściwością AggregationKind ustawioną na Shared lub Composite.
chickeninabiscuit


2
przydatny artykuł tutaj codeproject.com/Articles/22769/…
GibboK

6
Wiem, że już wiele razy na nie odpowiedziano, ale wydaje mi się, że najlepszym wytłumaczeniem, jakie kiedykolwiek przeczytałem w tej sprawie, jest: holub.com/goodies/uml/#composition
WLin

Odpowiedzi:


384

Dla dwóch obiektów, Fooa Barrelacje można zdefiniować

Skojarzenie - mam związek z przedmiotem. FoowykorzystujeBar

public class Foo { 
    void Baz(Bar bar) {
    } 
};

Kompozycja - jestem właścicielem obiektu i jestem odpowiedzialny za jego żywotność. Kiedy Fooumiera, to samoBar

public class Foo {
    private Bar bar = new Bar(); 
}

Agregacja - mam przedmiot, który pożyczyłem od kogoś innego. Kiedy Fooumiera, Barmoże żyć.

public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}

3
Wygląda na kod C # / Java. W takim przypadku zarówno kod stowarzyszenia, jak i kod agregacji są takie same. W obu przypadkach „pasek” jest po prostu przywoływany i Barobiekt może żyć.
Ajay,

@Jeff Foster: Mam pewne wątpliwości. Jeśli utworzę wystąpienie obiektu słupkowego w Baz (pasek słupkowy) {bar = new Bar (); } w pierwszym przypadku. Czy nadal będzie kojarzeniem, czy stanie się teraz kompozycją?
Saket

21
@Ajay: Agregacja zachowuje odwołanie do obiektów, co nie ma miejsca w przypadku skojarzenia. Stąd różnica w implementacji.
ABCD

17
Skojarzenie jest nieco silniejsze niż użycie jako parametru metody. Uważam, że fragment kodu stowarzyszenia bardziej odpowiada relacji zależności . możesz zajrzeć do artykułu związanego z Martinem Fowlerem
Ahmad Abdelghany,

5
@AhmadAbdelghany jest poprawne. Pierwszy przykład to relacja zależności. Trzeci służy do asocjacji i agregacji.
André Valenti,

122

Wiem, że to pytanie jest oznaczone jako C #, ale pojęcia to dość ogólne pytania, takie jak przekierowanie tutaj. Przedstawię tutaj mój punkt widzenia (nieco stronniczy z punktu widzenia java, gdzie czuję się bardziej komfortowo).

Kiedy myślimy o obiektowej naturze, zawsze myślimy o przedmiotach, klasie (schemacie obiektów) i relacjach między nimi. Obiekty są powiązane i oddziałują na siebie metodami. Innymi słowy, obiekt jednej klasy może korzystać z usług / metod świadczonych przez obiekt innej klasy. Ten rodzaj relacji określa się jako asocjację. .

Agregacja i kompozycja to podzbiory skojarzenia, co oznacza, że ​​są szczególnymi przypadkami skojarzenia.

wprowadź opis zdjęcia tutaj

  • Zarówno w przypadku agregacji, jak i kompozycji obiekt jednej klasy „posiada” obiekt innej klasy .
  • Ale jest subtelna różnica. W składzie obiekt klasy, który jest własnością obiektu należącego do klasy, nie może żyć samodzielnie (zwany także „relacją śmierci”). Zawsze będzie istniał jako część swojego obiektu będącego właścicielem, gdzie podobnie jak w agregacji obiekt zależny jest samodzielny i może istnieć, nawet jeśli obiekt będący właścicielem klasy jest martwy.
  • Tak więc w składzie, jeśli właścicielem obiektu jest zbiór śmieci, będzie to również posiadany obiekt, co nie występuje w przypadku agregacji.

Zmieszany?

Przykład składu : Rozważ przykład samochodu i silnika, który jest bardzo specyficzny dla tego samochodu (co oznacza, że ​​nie można go używać w żadnym innym samochodzie). Ten rodzaj relacji między samochodem a konkretnym silnikiem klasą nazywa się Composition. Obiekt klasy Car nie może istnieć bez obiektu klasy SpecificEngine, a obiekt SpecificEngine nie ma znaczenia bez klasy Car. Krótko mówiąc, klasa Car wyłącznie „jest właścicielem” klasy SpecificEngine.

Przykład agregacji : Teraz rozważ klasę Samochód i Koło klasy . Samochód potrzebuje obiektu Wheel do działania. Oznacza to, że obiekt Car posiada obiekt Wheel, ale nie możemy powiedzieć, że obiekt Wheel nie ma znaczenia bez obiektu Car. Może być bardzo dobrze stosowany w rowerze, ciężarówce lub innym obiekcie samochodowym.

Podsumowując -

Podsumowując, asocjacja jest bardzo ogólnym terminem stosowanym do przedstawienia, kiedy klasa korzysta z funkcjonalności dostarczonych przez inną klasę. Mówimy, że jest to kompozycja, jeśli jeden obiekt klasy nadrzędnej jest właścicielem innego obiektu klasy podrzędnej, a ten obiekt klasy podrzędnej nie może istnieć sensownie bez obiektu klasy nadrzędnej. Jeśli tak, to nazywa się Agregacja.

Więcej informacji tutaj. Jestem autorem strony http://opensourceforgeeks.blogspot.in i dodałem link powyżej do odpowiedniego postu, aby uzyskać więcej informacji.


8
Chciałem zapytać, dlaczego chciałeś odpowiedzieć na pytanie, na które już udzielono odpowiedzi, które zostało zadane ponad 5 lat temu, ale potem przeczytałem twój wpis na blogu i był on znacznie bardziej pouczający niż niektóre odpowiedzi tutaj. Pozytywne!
Donbhupi,

2
Zgadzam się z @Donbhupi, twoja odpowiedź jest znacznie bardziej pouczająca i poprawna niż wielu innych
zish

1
To naprawdę zabawne, gdy programiści C # i Java twierdzą, że używają kompozycji, gdy istnieje ona tylko na prymitywnych typach z tymi językami. Jeśli chcesz naprawdę zrozumieć kompozycję, musisz użyć C ++, w którym obiekty NAPRAWDĘ mogą być częścią innych obiektów. Nie tylko unosi się w pamięci stosu i trzyma do siebie wskaźniki i twierdzi, że jest kompozycja.
Wszyscy

@ Każdy doszedłem do tego samego wniosku co ty, ale nie jestem tego taki pewien. Na przykład, powiedzmy, że mam jedną klasę, która jest semantycznie własnością jednej konkretnej klasy, jednak posiadany obiekt to śmieci wyrzucane po tym, jak jego właściciel został już usunięty przez moduł wyrzucający śmieci, czy jest to uważane za kompozycję?
Paulo André Haacke

Czy możemy mieć kompozycję w kodzie ac # przy użyciu pamięci zarządzanej?
Paulo André Haacke

85

Stowarzyszenie jest uogólnioną koncepcją relacji. Obejmuje zarówno skład, jak i agregację.

Kompozycja ( mieszanina ) to sposób na zawinięcie prostych obiektów lub typów danych w jedną jednostkę . Kompozycje są kluczowym elementem składowym wielu podstawowych struktur danych

Agregacja ( kolekcja ) różni się od zwykłego składu tym, że nie implikuje własności. W składzie, gdy obiekt będący właścicielem jest niszczony, tak samo jak obiekty zawarte. Podsumowując, niekoniecznie jest to prawda.

Oba oznaczają relacje między przedmiotem i różnią się jedynie siłą.

Sztuczka, aby zapamiętać różnicę: ma A - A agregacja i O wn - c O mpositoin

wprowadź opis zdjęcia tutaj

Teraz obserwuj następujący obraz

relacje

wprowadź opis zdjęcia tutaj

Analogia:

Kompozycja : Poniższe zdjęcie to kompozycja obrazu, tzn. Użycie pojedynczych zdjęć w celu utworzenia jednego obrazu.
wprowadź opis zdjęcia tutaj

Agregacja : zbiór obrazów w jednym miejscu

wprowadź opis zdjęcia tutaj

Na przykład uniwersytet posiada różne wydziały, a każdy wydział ma wielu profesorów. Jeśli uniwersytet zostanie zamknięty, wydziały przestaną istnieć, ale profesorowie na tych wydziałach będą nadal istnieć. Dlatego uniwersytet może być postrzegany jako kompozycja wydziałów, podczas gdy wydziały mają agregację profesorów. Ponadto profesor może pracować na więcej niż jednym wydziale, ale wydział nie może być częścią więcej niż jednego uniwersytetu.


14
Po przeczytaniu tak dużo na ten temat, ta odpowiedź jest najbardziej intuicyjna i zrozumiała. Należy umieścić na wikipedii.
Jankapunkt

1
Pięknie artykułowane.
Sid

W odniesieniu do agregacji mówisz: „Obiekty potomne należą do samotnego rodzica”. To nie jest poprawne. Prawidłowy UML ma wspólną agregację, tzn. Dziecko należy do wielu rodziców. Potwierdzasz to w swoim przykładzie dotyczącym Wydziału jako agregacji Profesorów, ponieważ mówisz, że Profesor może pracować dla więcej niż jednego Wydziału.
www.admiraalit.nl

@ www.admiraalit.nl Wspólna agregacja AFAIK nie oznacza, że ​​„dziecko należy do wielu rodziców”, jest odwrotnie, wiele dzieci należy do tych samych rodziców. Jest to agregacja niekompozytowa, ponieważ nawet jeśli rodzice umrą, dzieci mogą przeżyć dłużej.
aderchox

65

Zależność (referencje)
Oznacza to, że nie ma koncepcyjnego powiązania między dwoma obiektami. np. referencje do obiektów EnrollmentService Obiekty dla studentów i przedmiotów (jako parametry metody lub typy zwracane)

public class EnrollmentService {
    public void enroll(Student s, Course c){}
}

Skojarzenie (has-a)
Oznacza to, że prawie zawsze istnieje związek między obiektami (są one powiązane). Obiekt zamówienia ma obiekt klienta

public class Order {
    private Customer customer
}

Agregacja (has-a + cała część)
Specjalny rodzaj powiązania, w którym istnieje relacja całości między dwoma obiektami. mogą jednak żyć bez siebie.

public class PlayList{
    private List<Song> songs;
}

Uwaga: najtrudniejszą częścią jest odróżnienie agregacji od normalnego skojarzenia. Szczerze mówiąc, myślę, że jest to otwarte na różne interpretacje.

Skład (ma + część + własność)
Specjalny rodzaj agregacji. An Apartmentskłada się z niektórych Rooms. Nie Roommoże istnieć bez Apartment. po usunięciu mieszkania usuwane są również wszystkie powiązane pokoje.

public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
}

1
Tak, jedyną trudną częścią w określaniu relacji między obiektami jest rozróżnienie między skojarzeniem a agregacją. Wszystko inne jest jasne. +1 ode mnie
Fouad Boukredine

28

Z postu Roberta Martina w komp. Obiekt :

Skojarzenie oznacza zdolność jednego wystąpienia do wysłania wiadomości do innego wystąpienia. Zwykle jest to implementowane za pomocą zmiennej wskaźnika lub odwołania do instancji, chociaż może być również implementowane jako argument metody lub tworzenie zmiennej lokalnej.

//[Example:]

//|A|----------->|B|

class A
{
  private:
    B* itsB;
};

Agregacja [...] jest typową relacją całość / część. Jest to dokładnie to samo, co skojarzenie z wyjątkiem tego, że instancje nie mogą mieć cyklicznych relacji agregacyjnych (tzn. Część nie może zawierać całości).

//[Example:]

//|Node|<>-------->|Node|

class Node
{
  private:
    vector<Node*> itsNodes;
};

Fakt, że jest to agregacja, oznacza, że ​​instancje węzła nie mogą tworzyć cyklu. Zatem jest to Drzewo Węzłów, a nie wykres Węzłów.

Skład [...] jest dokładnie taki, jak agregacja, z wyjątkiem tego, że czas życia „części” jest kontrolowany przez „całość”. Ta kontrola może być bezpośrednia lub przechodnia. Oznacza to, że „całość” może wziąć bezpośrednią odpowiedzialność za utworzenie lub zniszczenie „części” lub może zaakceptować już utworzoną część, a następnie przekazać ją innej osobie, która bierze za nią odpowiedzialność.

//[Example:]

//|Car|<#>-------->|Carburetor|

class Car
{
  public:
    virtual ~Car() {delete itsCarb;}
  private:
    Carburetor* itsCarb
};

1
Ile autorytetów ma ta definicja? Czy jest obsługiwany przez autorów standardu UML? Czy to obsługiwane przez narzędzia?
reinierpost

1
To Robert C. Martin. To dla mnie wystarczający autorytet :-)
Heliac

21

Jak powiedzieli inni, powiązanie to związek między obiektami, agregacja i kompozycja to rodzaje powiązań.

Z punktu widzenia implementacji agregację uzyskuje się poprzez posiadanie członka klasy przez odniesienie . Na przykład, jeśli klasa A agreguje obiekt klasy B, będziesz mieć coś takiego (w C ++):

class A {
    B & element;
  // or B * element;
};

Semantyka agregacji polega na tym, że gdy obiekt A zostanie zniszczony, przechowywany obiekt B nadal będzie istniał. Podczas korzystania z kompozycji istnieje silniejszy związek, zwykle poprzez przechowywanie członka według wartości :

class A {
    B element;
};

Tutaj, gdy obiekt A zostanie zniszczony, obiekt B, który zawiera, również zostanie zniszczony. Najłatwiejszym sposobem na osiągnięcie tego jest przechowywanie elementu pod względem wartości, ale można również użyć inteligentnego wskaźnika lub usunąć element członkowski w destruktorze:

class A {
    std::auto_ptr<B> element;
};

class A {
    B * element;

    ~A() {
        delete B;
    }
};

Ważne jest to, że w kompozycji obiekt kontenerowy jest właścicielem zawartego obiektu , podczas gdy w agregacji odwołuje się do niego.


8
To powinna być jedyna zaakceptowana odpowiedź. Kompozycja nie istnieje w C # i Javie, z wyjątkiem prymitywnych typów ... Jednak widzimy, że twórcy tych języków „wyjaśniają” kompozycję. Kompozycja oznacza, że ​​obiekt istnieje WEWNĄTRZ innego. W Javie i C # nie możesz nawet tego zrobić, wszystko jest na stercie i po prostu przytrzymujesz do tego wskaźnik, to naprawdę agregacja, a nie kompozycja. C ++ zapewnia kompozycję ..
Wszyscy

14

To zadziwiające, jak wiele zamieszania wiąże się z rozróżnieniem między powiązaniem , agregacją i kompozycją trzech koncepcji relacji .

Zauważ, że agregacja i skład terminów były używane w społeczności C ++, prawdopodobnie przez pewien czas, zanim zostały zdefiniowane jako specjalne przypadki skojarzenia w diagramach klas UML.

Głównym problemem jest powszechne i ciągłe nieporozumienie (nawet wśród ekspertów programistów), że koncepcja kompozycji zakłada zależność cyklu życia między całością i jej częściami, tak że części nie mogą istnieć bez całości, ignorując fakt, że istnieją również przypadki skojarzeń części-całość z częściami niepodzielnymi, w których części można oddzielić i przetrwać zniszczenie całości.

O ile mi wiadomo, to zamieszanie ma dwa źródła:

  1. W społeczności C ++ termin „agregacja” był używany w znaczeniu klasy definiującej atrybut do odwoływania się do obiektów innej niezależnej klasy (patrz np. [1]), co oznacza poczucie asocjacji w diagramach klas UML. Termin „kompozycja” został użyty dla klas, które definiują obiekty składowe dla swoich obiektów, tak że przy zniszczeniu obiektu złożonego te obiekty składowe są również niszczone.

  2. Na diagramach klas UML zarówno „agregacja”, jak i „kompozycja” zostały zdefiniowane jako specjalne przypadki skojarzeń reprezentujących relacje części-całości (które były omawiane w filozofii od dłuższego czasu). W ich definicjach rozróżnienie między „agregacją” a „kompozycją” opiera się na fakcie, że umożliwia podział części między dwiema lub więcej całościami. Definiują „kompozycje” jako posiadające części, których nie można udostępniać (na wyłączność), podczas gdy „agregacje” mogą udostępniać swoje części. Ponadto mówią coś takiego: bardzo często, ale nie we wszystkich przypadkach, kompozycje cechują się zależnością cyklu życia między całością i jej częściami, tak że części nie mogą istnieć bez całości.

Tak więc, podczas gdy UML umieścił terminy „agregacja” i „kompozycja” we właściwym kontekście (relacji całość-część), nie udało się ich zdefiniować w jasny i jednoznaczny sposób, wychwytując intuicje programistów. Nie jest to jednak zaskakujące, ponieważ istnieje tak wiele różnych właściwości (i niuansów implementacyjnych), jakie mogą mieć te relacje, a programiści nie zgadzają się, jak je wdrożyć.

Zobacz także moją rozszerzoną odpowiedź na pytanie SO z kwietnia 2009 r. Wymienioną poniżej.

A właściwość, która została przyjęta do zdefiniowania „kompozycji” między obiektami OOP w społeczności C ++ (i to przekonanie jest nadal powszechnie utrzymywane): zależność cyklu życia między dwoma powiązanymi obiektami (kompozytem i jego składnikiem), jest niezbyt charakterystyczne dla „kompozycji”, ponieważ możemy mieć takie zależności ze względu na integralność referencyjną również w innych typach skojarzeń.

Na przykład w odpowiedzi SO zaproponowano następujący wzorzec kodu dla „składu” :

final class Car {    
  private final Engine engine;

  Car(EngineSpecs specs) {
    engine = new Engine(specs);
  }

  void move() {
    engine.work();
  }
}

Respondent twierdził, że charakterystyczne dla „kompozycji” byłoby to, że żadna inna klasa nie mogła odwoływać się do komponentu / znać go. Jednak z pewnością nie jest to prawdą we wszystkich możliwych przypadkach „składu”. W szczególności, w przypadku silnika samochodu, producent samochodu, być może wdrożony przy pomocy innej klasy, może być zmuszony odwołać się do silnika, aby móc skontaktować się z właścicielem samochodu, ilekroć jest z tym problem.

[1] http://www.learncpp.com/cpp-tutorial/103-aggregation/

Dodatek - Niekompletna lista często zadawanych pytań na temat składu i agregacji w StackOverflow

[ Kwi 2009 ]
Agregacja a kompozycja [zamknięte jako oparte głównie na opiniach]
[ kwi 2009 ]
Jaka jest różnica między kompozycją a związkiem?
[ Maj 2009 ]
Różnica między skojarzeniem, agregacją a składem
[ Maj 2009 ]
Jaka jest różnica między składem a agregacją? [duplikat]
[ paź 2009 ]
Jaka jest różnica między agregacją, składem i zależnością? [oznaczone jako duplikat]
[ lis 2010 ]
Association vs. Aggregation [oznaczone jako duplikat]sie 2012 ]
[
Różnica w implementacji między agregacją a kompozycją w Javie
[ luty 2015 ]
UML - asocjacja lub agregacja (proste fragmenty kodu)


głosuj za niekompletną listą często zadawanych pytań.
Jacco

13

Stowarzyszenie

Skojarzenie reprezentuje związek między dwiema klasami. Może być jednokierunkowy (w jedną stronę) lub dwukierunkowy (w dwie strony)

na przykład:

  1. jednokierunkowy

Klient składa zamówienia

  1. dwukierunkowy

A jest żonaty z B.

B jest żonaty z A.

Zbiór

Agregacja jest rodzajem skojarzenia, ale z określonymi cechami. Agregacja jest relacją w jednej większej „całej” klasie zawiera jedną lub więcej mniejszych klas „części”. Przeciwnie, mniejsza klasa „części” jest częścią „całej” większej klasy .

na przykład:

klub ma członków

Klub („cały”) składa się z kilku członków klubu („części”). Członek ma życie poza klubem. Gdyby klub („cały”) miał umrzeć, członkowie („części”) nie zginęliby razem z nim. Ponieważ członek może należeć do wielu klubów („cały”).

Kompozycja

Jest to silniejsza forma agregacji. „Całość” odpowiada za tworzenie lub niszczenie jej „części”

Na przykład:

Szkoła ma wydziały

W tym przypadku szkoła („cała”) miałaby umrzeć, a wydział („części”) umarłby wraz z nią. Ponieważ każda część może należeć tylko do jednej „całości”.


W przypadku agregacji. Czy powinienem użyć go class Club(){ _member = new Member } lub przekazać jako odniesienieclass Club(){ addMember(Member member) { this._member = member } }
rzuć

12

Ważne jest, aby zrozumieć, dlaczego powinniśmy zawracać sobie głowę używaniem więcej niż jednej linii relacji. Najbardziej oczywistym powodem jest opisanie relacji rodzic-dziecko między klasami (kiedy rodzic usunął wszystkie swoje dziecko jest w rezultacie usunięte), ale bardziej bezsilnie chcemy rozróżnić proste powiązanie i skład w celu nałożenia ukrytych ograniczeń na widoczność i propagowanie zmian w pokrewnych klasach, co odgrywa istotną rolę w zrozumieniu i zmniejszeniu złożoności systemu.

Stowarzyszenie

Najbardziej abstrakcyjnym sposobem opisania statycznego związku między klasami jest użycie łącza asocjacyjnego, które po prostu stwierdza, że ​​istnieje jakiś rodzaj łącza lub zależności między dwiema klasami lub więcej.

Słabe skojarzenie

Klasa A może być powiązana z klasą B, aby pokazać, że jedna z jej metod obejmuje parametr instancji klasy B lub zwraca instancję klasy B.

Silne stowarzyszenie

Klasa A może być również powiązana z klasą B, aby pokazać, że zawiera odwołanie do instancji klasy B.

Agregacja (wspólne stowarzyszenie)

W przypadkach, w których istnieje część relacji między klasą A (całą) a klasą B (część), możemy być bardziej konkretni i użyć linku agregacyjnego zamiast linku asocjacyjnego, podkreślając, że klasę B można również agregować według innych klas w aplikacji ( dlatego agregacja jest również znana jako asocjacja wspólna).

wprowadź opis zdjęcia tutaj

Ważne jest, aby pamiętać, że link agregacyjny nie wskazuje w żaden sposób, że ClassA jest właścicielem ClassB, ani że istnieje relacja rodzic-dziecko (gdy rodzic usunie wszystkie swoje dziecko jest usuwane) między nimi. Wręcz przeciwnie! Łącze agregacyjne zwykle używane do podkreślenia, że ​​klasa A nie jest wyłącznym kontenerem klasy B, ponieważ w rzeczywistości klasa B ma inny kontener.

Agregacja a asocjacja Link asocjacji może zastąpić link agregacji w każdej sytuacji, podczas gdy agregacja nie może zastąpić asocjacji w sytuacjach, w których istnieje tylko „słabe powiązanie” między klasami, tj. Klasa A ma metody, które zawierają parametr klasy B, ale klasa A nie przytrzymaj odwołanie do wystąpienia klasy B.

Martin Fowler sugeruje, że link agregacyjny nie powinien być w ogóle stosowany, ponieważ nie ma żadnej wartości dodanej i zaburza spójność, cytując Jim Rumbaugh „Pomyśl o tym jak o modelującym placebo”.

Kompozycja (nieprzydzielone skojarzenie)

Powinniśmy być bardziej konkretni i używać linku kompozycji w przypadkach, gdy oprócz części relacji między klasą A i klasą B - istnieje silna zależność między nimi w cyklu życia, co oznacza, że ​​po usunięciu klasy A, w wyniku tego klasa B również zostaje usunięta

wprowadź opis zdjęcia tutaj

Łącze kompozycji pokazuje, że klasa (kontener, całość) ma wyłączną własność nad innymi klasami (częściami), co oznacza, że ​​obiekt kontenera i jego części stanowią relację rodzic-dziecko.

W przeciwieństwie do asocjacji i agregacji, w przypadku korzystania z relacji kompozycji klasa złożona nie może pojawiać się jako typ zwracany lub typ parametru klasy złożonej. W związku z tym zmiany w klasie złożonej nie mogą rozprzestrzeniać się na resztę systemu. W konsekwencji użycie kompozycji ogranicza wzrost złożoności wraz ze wzrostem systemu.

Złożoność systemu pomiarowego

Złożoność systemu można zmierzyć po prostu patrząc na diagram klasy UML i oceniając linie powiązania, agregacji i składu. Metodą pomiaru złożoności jest określenie, na ile klas wpływ może mieć zmiana określonej klasy. Jeśli klasa A eksponuje klasę B, to teoretycznie wpływ na każdą klasę korzystającą z klasy A mogą mieć zmiany w klasie B. Suma liczby klas potencjalnie dotkniętych przez każdą klasę w systemie stanowi całkowitą złożoność systemu.

Możesz przeczytać więcej na moim blogu: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html



Dobra odpowiedź. 1) Pytanie do przykładu kompozycji: Leng and Hand (kompozycja) Osoba. jeśli utworzę klasę Zwierzęta i sen, to Sen (agregacja) Osoba; Sen (agregacja) Zwierzę. Czy to jest poprawne? 2). Ręka skład Osoba: class Person() { private hand = new Hand }. Agregacja snu Osoba class Person() { private sleep = new Sleep }Czy jest poprawna, użyj klucza „nowy” w trybie uśpienia? czy powinienem przekazać go jako odniesienie, ponieważ jest agregacją? class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }
roll

7

Kompozycja (jeśli usuniesz „całość”, „część” zostanie również automatycznie usunięta - „Własność”)

  • Twórz obiekty swojej istniejącej klasy w nowej klasie. Nazywa się to kompozycją, ponieważ nowa klasa składa się z obiektów istniejących klas.

  • Zwykle używaj normalnych zmiennych składowych.

  • Może używać wartości wskaźnika, jeśli klasa kompozycji automatycznie obsługuje alokację / dezalokację odpowiedzialną za tworzenie / niszczenie podklas.

wprowadź opis zdjęcia tutaj

Kompozycja w C ++

#include <iostream>
using namespace std;
/********************** Engine Class ******************/
class Engine
{
    int nEngineNumber;
    public:
    Engine(int nEngineNo);
    ~Engine(void);
};
Engine::Engine(int nEngineNo)
{
    cout<<" Engine :: Constructor " <<endl;
}
Engine::~Engine(void)
{
    cout<<" Engine :: Destructor " <<endl;
}
/********************** Car Class ******************/
class Car
{
    int nCarColorNumber;
    int nCarModelNumber;
    Engine objEngine;
    public:
    Car (int, int,int);
    ~Car(void);
};
Car::Car(int nModelNo,int nColorNo, int nEngineNo):
nCarModelNumber(nModelNo),nCarColorNumber(nColorNo),objEngine(nEngineNo)
{
    cout<<" Car :: Constructor " <<endl;
}
Car::~Car(void)
{
    cout<<" Car :: Destructor " <<endl;
    Car
    Engine
    Figure 1 : Composition
}
/********************** Bus Class ******************/
class Bus
{
    int nBusColorNumber;
    int nBusModelNumber;
    Engine* ptrEngine;
    public:
    Bus(int,int,int);
    ~Bus(void);
};
Bus::Bus(int nModelNo,int nColorNo, int nEngineNo):
nBusModelNumber(nModelNo),nBusColorNumber(nColorNo)
{
    ptrEngine = new Engine(nEngineNo);
    cout<<" Bus :: Constructor " <<endl;
}
Bus::~Bus(void)
{
    cout<<" Bus :: Destructor " <<endl;
    delete ptrEngine;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    // Composition using simple Engine in a car object
    {
        cout<<"------------- Inside Car Block ------------------"<<endl;
        Car objCar (1, 2,3);
    }
    cout<<"------------- Out of Car Block ------------------"<<endl;
    // Composition using pointer of Engine in a Bus object
    {
        cout<<"------------- Inside Bus Block ------------------"<<endl;
        Bus objBus(11, 22,33);
    }
    cout<<"------------- Out of Bus Block ------------------"<<endl;
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

Wynik

--------------- Start Of Program --------------------
------------- Inside Car Block ------------------
Engine :: Constructor
Car :: Constructor
Car :: Destructor
Engine :: Destructor
------------- Out of Car Block ------------------
------------- Inside Bus Block ------------------
Engine :: Constructor
Bus :: Constructor
Bus :: Destructor
Engine :: Destructor
------------- Out of Bus Block ------------------
--------------- End Of Program --------------------

Agregacja (jeśli usuniesz „całość”, „Część” może istnieć - „Brak własności”)

  • Agregacja jest szczególnym typem kompozycji, w której nie sugeruje się żadnej własności między złożonym obiektem a podobiektami. Gdy agregat jest niszczony, podobiekty nie są niszczone.

  • Zazwyczaj używaj zmiennych wskaźnikowych / zmiennych referencyjnych, które wskazują na obiekt, który żyje poza zakresem klasy agregującej

  • Może używać wartości referencyjnych wskazujących na obiekt, który żyje poza zakresem klasy agregującej

  • Nie odpowiada za tworzenie / niszczenie podklas

wprowadź opis zdjęcia tutaj

Kod agregacyjny w C ++

#include <iostream>
#include <string>
using namespace std;
/********************** Teacher Class ******************/
class Teacher
{
    private:
    string m_strName;
    public:
    Teacher(string strName);
    ~Teacher(void);
    string GetName();
};
Teacher::Teacher(string strName) : m_strName(strName)
{
    cout<<" Teacher :: Constructor --- Teacher Name :: "<<m_strName<<endl;
}
Teacher::~Teacher(void)
{
    cout<<" Teacher :: Destructor --- Teacher Name :: "<<m_strName<<endl;
}
string Teacher::GetName()
{
    return m_strName;
}
/********************** Department Class ******************/
class Department
{
    private:
    Teacher *m_pcTeacher;
    Teacher& m_refTeacher;
    public:
    Department(Teacher *pcTeacher, Teacher& objTeacher);
    ~Department(void);
};
Department::Department(Teacher *pcTeacher, Teacher& objTeacher)
: m_pcTeacher(pcTeacher), m_refTeacher(objTeacher)
{
    cout<<" Department :: Constructor " <<endl;
}
Department::~Department(void)
{
    cout<<" Department :: Destructor " <<endl;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    {
        // Create a teacher outside the scope of the Department
        Teacher objTeacher("Reference Teacher");
        Teacher *pTeacher = new Teacher("Pointer Teacher"); // create a teacher
        {
            cout<<"------------- Inside Block ------------------"<<endl;
            // Create a department and use the constructor parameter to pass the teacher to it.
            Department cDept(pTeacher,objTeacher);
            Department
            Teacher
            Figure 2: Aggregation
        } // cDept goes out of scope here and is destroyed
        cout<<"------------- Out of Block ------------------"<<endl;
        // pTeacher still exists here because cDept did not destroy it
        delete pTeacher;
    }
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

Wynik

--------------- Start Of Program --------------------
Teacher :: Constructor --- Teacher Name :: Reference Teacher
Teacher :: Constructor --- Teacher Name :: Pointer Teacher
------------- Inside Block ------------------
Department :: Constructor
Department :: Destructor
------------- Out of Block ------------------
Teacher :: Destructor --- Teacher Name :: Pointer Teacher
Teacher :: Destructor --- Teacher Name :: Reference Teacher
--------------- End Of Program --------------------

Ktokolwiek zepsuł głosował na tę odpowiedź. Czy możesz wyjaśnić powód, dla którego głosujesz w dół?
Saurabh Raoot

To, co naprawdę wprawia mnie w zakłopotanie, to fakt, że w wielu przypadkach to nie właściciel jest właścicielem rzeczy, ale to, co posiada, „trzyma” właściciela. Na przykład samochód nie ma wskaźnika typu Silnik *, ale klasa silnika ma element typu Samochód do przechowywania samochodu, który jest jego właścicielem. Nie do końca to rozumiem, szczególnie relacja między klasami w tym przypadku.
dudu,

6

Problem z tymi odpowiedziami jest taki, że stanowią one połowę historii: wyjaśniają, że agregacja i kompozycja są formami skojarzeń, ale nie twierdzą, czy możliwe jest, aby żadne z nich nie było.

Na podstawie krótkich odczytów wielu postów na temat SO i niektórych dokumentów UML uznaję, że istnieją 4 główne konkretne formy stowarzyszenia klas:

  1. skład: A składa się z B; B nie istnieje bez A, jak pokój w domu
  2. agregacja: A has-a B; B może istnieć bez A, jak uczeń w klasie
  3. zależność: A uses-a B; brak zależności cyklu życia między A i B, jak parametr wywołania metody, wartość zwracana lub tymczasowe utworzone podczas wywołania metody
  4. uogólnienie: A jest-a B.

Kiedy relacja między dwoma bytami nie jest jedną z nich, można ją po prostu nazwać „skojarzeniem” w ogólnym znaczeniu tego słowa i dalej opisywać inne sposoby (uwaga, stereotyp itp.).

Domyślam się, że „ogólne skojarzenie” ma być stosowane przede wszystkim w dwóch okolicznościach:

  • kiedy specyfika relacji jest wciąż opracowywana; taka relacja na diagramie powinna zostać jak najszybciej przekształcona w to, czym faktycznie jest / będzie (jedna z pozostałych 4).
  • gdy relacja nie pasuje do żadnej z 4 z góry określonych przez UML; „ogólne” skojarzenie wciąż daje ci możliwość przedstawienia relacji, która nie jest „jednym z pozostałych”, dzięki czemu nie utkniesz przy użyciu niewłaściwej relacji z notatką „to nie jest tak naprawdę agregacja, to po prostu UML nie ma żadnego innego symbolu, którego moglibyśmy użyć „

1
Jak dokładnie wdrożyłbyś ogólne skojarzenie, gdyby wszystkie inne opcje zostały wykluczone? Jeśli A nie składa się z B (wartość B jest w A), A nie jest agregacją B (odniesienie B nie znajduje się w A), B nie jest dziedziczone / realizowane z A ani B nie jest używane jako zwrot, parametr lub wewnątrz użycie funkcji A, w zasadzie nie masz żadnej relacji.
Dziekan P

1
@DeanP Może na razie być ogólny, a później zostanie przekonwertowany na jeden z 4 (wtedy stanie się możliwy do wdrożenia); LUB może to być związek, który nie pasuje do 4, np. Powiedz, że chcesz powiązania, które oznacza „wygląda”, bez ogólnego skojarzenia będziesz zmuszony użyć jednego z 4, wprowadzając w błąd czytelnika, a jeśli użyjesz ogólny, prawdopodobnie dodasz adnotację lub umieścisz notatkę wyjaśniającą, co to jest, a większość ludzi czyta notatki tylko wtedy, gdy nie rozumie symbolu;)
Oliver

5

Myślę, że ten link odrobi pracę domową: http://ootips.org/uml-hasa.html

Aby zrozumieć warunki, pamiętam przykład z moich wczesnych dni programowania:

Jeśli masz obiekt „szachownicy”, który zawiera obiekty „pudełka” będące kompozycją, ponieważ usunięcie „szachownicy” nie ma już powodu, aby istniały pola.

Jeśli masz obiekt „kwadratowy”, który ma obiekt „kolorowy”, a kwadrat zostanie usunięty, obiekt „kolorowy” może nadal istnieć, czyli agregacja

Oba są skojarzeniami , główna różnica dotyczy pojęć


5

Kompozycja : w tym momencie, gdy zniszczysz obiekt (szkołę), inny obiekt (klasy), który jest z nim związany, również zostanie zniszczony. Oba nie mogą istnieć niezależnie.

Agregacja : jest to coś dokładnie przeciwnego do powyższego ( Composition) powiązania, w którym po zabiciu obiektu ( Company) drugi Employeeszwiązany z nim obiekt ( ) może istnieć samodzielnie.

Stowarzyszenie .
Skład i agregacja to dwie formy asocjacji.


1
Ściśle mówiąc, pracownicy firmy nie mogą istnieć bez firmy. To prawda, że ​​nie zabijasz ludzi, ale oni nie są już pracownikami tej firmy. Myślę więc, że lepsza analogia byłaby z Oddziałem i Pracownikami, gdzie nawet jeśli oddział zostanie zamknięty, mogą nadal być pracownikami firmy.
Alexander

1
tak, absolutnie. Zgadzam się ... +1 Dzięki @AlexPopov za wskazanie tego. :)
Kulasangar

4
    Simple rules:
    A "owns" B = Composition : B has no meaning or purpose in the system 
    without A
    A "uses" B = Aggregation : B exists independently (conceptually) from A
    A "belongs/Have" B= Association; And B exists just have a relation
    Example 1:

    A Company is an aggregation of Employees.
    A Company is a composition of Accounts. When a Company ceases to do 
    business its Accounts cease to exist but its People continue to exist. 
    Employees have association relationship with each other.

    Example 2: (very simplified)
    A Text Editor owns a Buffer (composition). A Text Editor uses a File 
    (aggregation). When the Text Editor is closed,
    the Buffer is destroyed but the File itself is not destroyed.

3

W bardzo prostym zdaniu:
Agregacja i Kompozycja są podzbiorami asocjacji.

  • A używa B -> jest to agregacja

  • Potrzeba B -> to kompozycja.

Przeczytaj więcej tutaj .


2

Chciałbym zilustrować, w jaki sposób te trzy warunki są zaimplementowane w Railsach. ActiveRecord nazywa dowolny rodzaj relacji między dwoma modelami association. Bardzo często nie można znaleźć warunków, compositiona aggregationpodczas czytania dokumentacji lub artykułów związanych z ActiveRecord. Powiązanie jest tworzone przez dodanie jednego z makr klasy asocjacji do treści klasy. Niektóre z tych makr belongs_to, has_one, has_manyetc ..

Jeśli chcemy uruchamiamy compositionalbo aggregationmusimy dodać belongs_todo posiadanego modelu (zwany także dzieci) i has_oneczy has_manydo modelu posiadającego (zwany także dominującej). Wether skonfigurowaliśmy compositionlub aggregationzależy od opcji, które przekazujemy do belongs_topołączenia w modelu potomnym. Przed Railsami 5, konfigurowanie belongs_tobez żadnych opcji stworzonych aggregation, dziecko mogło istnieć bez rodzica. Jeśli chcieliśmy a composition, musieliśmy to wyraźnie zadeklarować, dodając opcję required: true:

class Room < ActiveRecord::Base
  belongs_to :house, required: true
end

W Rails 5 zostało to zmienione. Teraz, zadeklarowanie belongs_topowiązania tworzy compositiondomyślnie, że dziecko nie może istnieć bez rodzica. Powyższy przykład może zostać przepisany jako:

class Room < ApplicationRecord
  belongs_to :house
end

Jeśli chcemy, aby obiekt potomny istniał bez elementu nadrzędnego, musimy to wyraźnie zadeklarować za pomocą opcji optional

class Product < ApplicationRecord
  belongs_to :category, optional: true
end

2

Od: książka Remo H. Jansen „Beginning React: Learning TypeScript 2.x - Second Edition”:

Nazywamy stowarzyszeniem relacjami, których obiekty mają niezależny cykl życia, w którym nie ma własności tych obiektów. Spójrzmy na przykład nauczyciela i ucznia. Wielu uczniów można powiązać z jednym nauczycielem, a jednego ucznia można powiązać z wieloma nauczycielami, ale obaj mają niezależne cykle życia (obaj mogą tworzyć i usuwać niezależnie). Kiedy więc nauczyciel opuszcza szkołę, nie musimy usuwać żadnych uczniów, a kiedy uczeń opuszcza szkołę, nie musimy usuwać żadnych nauczycieli.

Nazywamy agregacją relacjami, których obiekty mają niezależny cykl życia, ale istnieje własność, a obiekty potomne nie mogą należeć do innego obiektu nadrzędnego. Weźmy przykład telefonu komórkowego i baterii telefonu komórkowego. Pojedyncza bateria może należeć do telefonu, ale jeśli telefon przestanie działać, a my usuniemy go z naszej bazy danych, bateria telefonu nie zostanie usunięta, ponieważ może nadal działać. Podsumowując, dopóki istnieje własność, obiekty mają swój cykl życia

Używamy terminu „ skład” w odniesieniu do relacji, których obiekty nie mają niezależnego cyklu życia, a jeśli obiekt nadrzędny zostanie usunięty, wszystkie obiekty podrzędne również zostaną usunięte. Weźmy przykład związku między pytaniami a odpowiedziami. Pojedyncze pytania mogą mieć wiele odpowiedzi, a odpowiedzi nie mogą należeć do wielu pytań. Jeśli usuniemy pytania, odpowiedzi zostaną automatycznie usunięte.


1

Skojarzenie jest relacją między dwiema odrębnymi klasami, a powiązanie może być dowolnego typu, powiedzmy jeden do jednego, jeden do maja itp. Łączy dwa całkowicie odrębne byty.

Agregacja to specjalna forma asocjacji, która jest jednokierunkową, jednokierunkową relacją między klasami (lub jednostkami), na przykład klasami portfela i pieniędzy. Portfel ma Pieniądze, ale pieniądze niekoniecznie muszą mieć Portfel, więc jest to relacja jednokierunkowa. W tej relacji oba wpisy mogą przetrwać, jeśli inne się zakończą. W naszym przykładzie, jeśli klasa Wallet nie jest obecna, nie oznacza to, że klasa Money nie może istnieć.

Kompozycja jest ograniczoną formą agregacji, w której dwa byty (lub można powiedzieć, że klasy) są od siebie wysoce zależne. Na przykład dla człowieka i serca. Człowiek potrzebuje serca, aby żyć, a serce potrzebuje ciała ludzkiego, aby przetrwać. Innymi słowy, gdy klasy (byty) są od siebie zależne, a ich długość życia jest taka sama (jeśli jedna umiera, to druga też), to jest to skład. Klasa serca nie ma sensu, jeśli nie ma klasy ludzkiej.


1

https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/

Skład: to związek „częściowy”.

na przykład „silnik jest częścią samochodu”, „serce jest częścią ciała”.

wprowadź opis zdjęcia tutaj

Stowarzyszenie: to relacja typu „ma”

Na przykład, załóżmy, że mamy dwie klasy, wtedy te dwie klasy są nazywane relacjami typu „ma-a”, jeśli obie te jednostki współużytkują obiekt dla pewnej pracy, a jednocześnie mogą istnieć bez wzajemnej zależności lub obie mają swoje własne życie.

wprowadź opis zdjęcia tutaj

Powyższy przykład pokazuje relację powiązania z powodu zarówno klasy pracownika, jak i menedżera, które wykorzystują obiekt siebie oraz swój niezależny cykl życia.

Agregacja: opiera się na relacji „ma-a” i jest specjalną formą skojarzenia

na przykład „Student” i „adres”. Każdy uczeń musi mieć adres, aby relacja między klasą ucznia a klasą adresu była relacją typu „Has-A”, ale odwrotnie nie jest prawdą.

wprowadź opis zdjęcia tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.