Agregacja a kompozycja [zamknięte]

90

Trudno mi było zrozumieć różnicę między kompozycją a agregacją w UML. Czy ktoś może mi zaproponować dobre porównanie i kontrast między nimi? Chciałbym również nauczyć się rozpoznawać różnice między nimi w kodzie i / lub zobaczyć krótki przykład oprogramowania / kodu.

Edycja: Jednym z powodów, dla których pytam, jest odwrotna dokumentacja, którą wykonujemy w pracy. Napisaliśmy kod, ale musimy wrócić i stworzyć diagramy klas dla kodu. Chcielibyśmy tylko odpowiednio uchwycić skojarzenia.

Dave
źródło
Zobacz także Implementation-
Difference
Sprawdź przykład oparty na kodzie pod adresem: stackoverflow.com/questions/731802/…
Almir Campos
UML 2.5 wyjaśnił różnicę. Zobacz ramkę na str. 110. Głosuję więc za ponownym otwarciem tego.
qwerty_so
Nie, UML 2.5 nie wyjaśnił definicji kompozycji, a raczej pozostał niejasny co do niej, ponieważ mówią również: „Obiekt części może zostać usunięty z obiektu złożonego przed usunięciem obiektu złożonego, a zatem nie może zostać usunięty w ramach obiekt złożony ”. Zobacz moją odpowiedź poniżej ( stackoverflow.com/questions/734891/… ), gdzie próbowałem wyjaśnić znaczenie kompozycji. Proszę zagłosuj za moją odpowiedź, aby pokazać, że w SO prawidłowa odpowiedź wygrywa w końcu :-) [lub przeciwnie głosuj wszystkie niepoprawne odpowiedzi]
Gerd Wagner

Odpowiedzi:

91

Rozróżnienie między agregacją a kompozycją zależy od kontekstu.

Weźmy przykład samochodu podany w innej odpowiedzi - tak, to prawda, że ​​wydech samochodowy może stać „sam”, więc może nie być w składzie z samochodem - ale to zależy od zastosowania. Jeśli zbudujesz aplikację, która faktycznie ma do czynienia z samodzielnymi spalinami samochodowymi (aplikacja do zarządzania warsztatem samochodowym?), Wybierz agregację. Ale jeśli jest to prosta gra wyścigowa, a wydech samochodowy służy tylko jako część samochodu - cóż, kompozycja byłaby całkiem dobra.

Szachownica? Taki sam problem. Bierka szachowa nie istnieje bez szachownicy tylko w niektórych zastosowaniach. W innych (na przykład u producenta zabawek) figura szachowa z pewnością nie może zostać złożona w szachownicę.

Sytuacja się pogarsza, gdy próbujesz odwzorować kompozycję / agregację na Twój ulubiony język programowania. W niektórych językach różnica może być łatwiejsza do zauważenia („przez odniesienie” a „według wartości”, gdy sprawy są proste), ale w innych może w ogóle nie istnieć.

I ostatnia rada? Nie trać zbyt wiele czasu na ten problem. To nie jest tego warte. To rozróżnienie jest mało przydatne w praktyce (nawet jeśli masz całkowicie czytelną „kompozycję”, nadal możesz chcieć zaimplementować ją jako agregację ze względów technicznych - na przykład buforowanie).

Sześciokąt
źródło
1
Powiedziałem raczej kwadrat szachowy niż figurę szachową, ale wszystkie ważne punkty.
David M
2
Zdecydowanie nie zgadzam się z nastawieniem „To nie jest tego warte”. Jeśli nie zastanowisz się, kto „jest właścicielem” obiektu i jest odpowiedzialny za jego żywotność, otrzymasz bardzo kiepski kod związany z CRUD obiektu, szczególnie czyszczenie, z zerowymi wskaźnikami latającymi dookoła, gdy hierarchie obiektów pozostają w złym stanie.
Chris Kessel
9
Tak, nie powinieneś tracić czasu na tę kwestię: UML jest językiem OOA / OOD; Agregacja / kompozycja jest zwykle decyzją, którą najlepiej odłożyć do czasu rozpoczęcia operacji. Jeśli spróbujesz umieścić zbyt wiele szczegółów w swoich modelach UML, ryzykujesz paraliżem analizy.
szympans
13
+1 za „nie trać na to zbyt wiele czasu”. To właśnie chciałem usłyszeć!
Ronnie
8
„nie trać na to zbyt wiele czasu” Dlaczego ankieterzy tego nie rozumieją?
titogeo,
97

Jako zasada: wprowadź opis obrazu tutaj

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

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

W kompozycji (osoba, serce, ręka) „obiekty podrzędne” (serce, ręka) zostaną zniszczone, gdy tylko osoba zostanie zniszczona.

W agregacji (miasto, drzewo, samochód) „obiekty podrzędne” (drzewo, samochód) NIE zostaną zniszczone po zniszczeniu miasta.

Najważniejsze jest to, że kompozycja kładzie nacisk na wzajemne istnienie, a łącznie ta właściwość NIE jest wymagana.

Hoa Nguyen
źródło
2
wzajemne istnienie, dobry B-)
jxramos
Doceniam Twój wysiłek. Bardzo dobre wyjaśnienie i każdy laik może to zrozumieć.
Ravindran Kanniah
Najprostsze i najlepsze wyjaśnienie, z jakim się spotkałem.
Akash Raghav
najlepsze wyjaśnienie :)
Xiabili
UML 2.5 wyjaśnił różnicę. Zobacz ramkę na str. 110. Więc teraz twoja odpowiedź jest po prostu błędna,
qwerty_so
51

Kompozycja i agregacja to typy asocjacji. Są bardzo blisko spokrewnieni, a pod względem programowania nie wydaje się, aby między nimi istniała duża różnica. Spróbuję wyjaśnić różnicę między tymi dwoma przykładami kodu Java

Agregacja : obiekt istnieje poza drugim, jest tworzony na zewnątrz, więc jest przekazywany jako argument (na przykład) do konstruktora. Np. Ludzie - samochód. Samochód powstaje w innym kontekście, a następnie staje się własnością osoby.

// 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;
  }
}

Kompozycja : obiekt istnieje lub ma sens tylko wewnątrz drugiego, jako część innego. Np. Ludzie - serce. Nie tworzysz serca i nie przekazujesz go innej osobie. Zamiast tego serce zostaje stworzone, gdy zostaje stworzony człowiek.

// 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”);
  }
}

Wyjaśniono tutaj na przykładzie Różnica między agregacją a kompozycją

vsingh
źródło
5
Jak dotąd jedna z najlepszych odpowiedzi. Schludnie :)
Rohit Singh
6
Najlepszy przykład kodu Java pokazujący, kiedy obiekt może istnieć z innymi obiektami (kompozycja) lub bez (agregacja).
Michał Dobi Dobrzański
proszę, chcę wiedzieć, czy powinniśmy używać wersji final do kompozycji, czy nie?
Outreagous ONE
36

Kompozycja oznacza, że ​​obiekty potomne mają wspólną długość życia z rodzicem. Agregacja nie. Na przykład szachownica składa się z kwadratów szachowych - te szachy tak naprawdę nie istnieją bez szachownicy. Jednak samochód jest zbiorem części - spaliny samochodowe są nadal spalinami samochodowymi, jeśli nie są w tym czasie częścią samochodu.

David M.
źródło
18

Przykładem, którego się nauczyłem, były palce u dłoni. Twoja ręka składa się z palców. Jest ich właścicielem. Jeśli dłoń umiera, umierają palce. Nie możesz „łączyć” palców. Nie możesz po prostu chwycić dodatkowych palców i dowolnie przyczepiać i odłączać je od dłoni.

Wartość tutaj, z punktu widzenia projektu, jest często związana z żywotnością obiektu, jak powiedział inny plakat. Powiedzmy, że masz klienta i on ma konto. To konto jest „skomponowanym” obiektem klienta (przynajmniej w większości kontekstów, które przychodzą mi do głowy). Jeśli usuniesz Klienta, Konto samo w sobie nie będzie miało wartości, więc również zostanie usunięte. W przypadku tworzenia obiektów często jest odwrotnie. Ponieważ Konto ma znaczenie tylko w kontekście Klienta, utworzenie Konta byłoby częścią tworzenia Klienta (lub, jeśli robisz to leniwie, byłoby to częścią jakiejś transakcji Klienta).

Przy projektowaniu warto pomyśleć o tym, które obiekty posiadają (tworzą) inne obiekty, a które tylko odwołują się (agregują) do innych obiektów. Może pomóc określić, gdzie leży odpowiedzialność za tworzenie / czyszczenie / aktualizację obiektów.

Jeśli chodzi o kod, często trudno powiedzieć. Prawie wszystko w kodzie jest odwołaniem do obiektu, więc może nie być oczywiste, czy obiekt, do którego istnieje odwołanie, jest utworzony (posiadany), czy zagregowany.

Chris Kessel
źródło
15

To zdumiewające, jak wiele nieporozumień istnieje w kwestii rozróżnienia między częścią-całością - koncepcjami skojarzeń , agregacją i kompozycją . Głównym problemem jest powszechne nieporozumienie (nawet wśród doświadczonych programistów i autorów UML), że pojęcie kompozycji zakłada zależność cyklu życia między całością a jej częściami, tak że części nie mogą istnieć bez całości. Jednak pogląd ten pomija fakt, że istnieją również przypadki skojarzeń części-całości z częściami niepodlegającymi współużytkowaniu, w których części można oddzielić od całości i przetrwać zniszczenie.

W dokumencie specyfikacji UML definicja terminu „skład” zawsze implikowała części, których nie można udostępniać, ale nie było jasne, co jest definiującą cechą „składu”, a co jest jedynie cechą opcjonalną. Nawet w nowej wersji (z 2015 r.), UML 2.5, po próbie udoskonalenia definicji terminu „skład”, pozostaje on nadal niejednoznaczny i nie dostarcza żadnych wskazówek, jak modelować skojarzenia części całości z części wspólne, w przypadku których części można odłączyć i przetrwać zniszczenie całości, w przeciwieństwie do przypadku, gdy części nie można odłączyć i są one niszczone razem z całością. Mówią

Jeśli obiekt złożony zostanie usunięty, wszystkie wystąpienia jego części, które są obiektami, zostaną usunięte wraz z nim.

Ale jednocześnie mówią też

Obiekt części może zostać usunięty z obiektu złożonego przed usunięciem obiektu złożonego, a zatem nie może zostać usunięty jako część obiektu złożonego.

To zamieszanie wskazuje na niekompletność definicji UML, która nie uwzględnia zależności cyklu życia między komponentami i kompozytami. Dlatego ważne jest, aby zrozumieć, w jaki sposób można ulepszyć definicję UML, wprowadzając stereotyp UML dla kompozycji „ nierozłącznych”, w których komponentów nie można odłączyć od ich kompozytu, a zatem należy je zniszczyć za każdym razem, gdy ich kompozyt zostanie zniszczony.

1) Skład

Jak wyjaśnił Martin Fowler , głównym problemem charakteryzującym kompozycję jest to, że „przedmiot może być tylko częścią jednej relacji kompozycji”. Jest to również wyjaśnione w doskonałym wpisie na blogu UML Composition vs Aggregation vs Association autorstwa Geerta Bellekensa. Oprócz tej definiującej cechy kompozycji (posiadającej wyłączne lub niepodlegające współużytkowaniu części), kompozycja może również charakteryzować się zależnością cyklu życia między kompozytem a jego składnikami. W rzeczywistości istnieją dwa rodzaje takich zależności:

  1. Ilekroć składnik musi być zawsze dołączony do kompozytu lub, innymi słowy, gdy ma obowiązkowy kompozyt , co wyraża się liczbą „dokładnie jednej” po stronie kompozytu na linii składu, wówczas należy go użyć ponownie w (lub ponownie dołączony) do innego kompozytu lub zniszczony, gdy obecny kompozyt zostanie zniszczony. Ilustruje to skład pomiędzy Persona Heart, pokazany na poniższym diagramie. Serce zostaje zniszczone lub przeszczepione innej osobie po śmierci właściciela.
  2. Zawsze, gdy komponentu nie można odłączyć od swojego kompozytu, czyli innymi słowy, gdy jest nierozłączny , wtedy i tylko wtedy komponent musi zostać zniszczony, gdy jego kompozyt zostanie zniszczony. Przykładem takiej kompozycji z nierozłącznymi częściami jest kompozycja między Persona Brain.

wprowadź opis obrazu tutaj

Podsumowując, zależności cyklu życia mają zastosowanie tylko do określonych przypadków składu, ale nie ogólnie, dlatego nie są cechą definiującą.

Zgodnie ze specyfikacją UML: „Część może zostać usunięta z wystąpienia złożonego przed usunięciem wystąpienia złożonego, a zatem nie może zostać usunięta jako część wystąpienia złożonego”. W przykładzie a Car- Enginekompozycji, jak pokazano na poniższym schemacie, wyraźnie widać, że silnik można odłączyć od samochodu przed zniszczeniem samochodu, w którym to przypadku silnik nie ulega zniszczeniu i można go ponownie użyć. Jest to implikowane przez zerową lub jedną krotność po stronie złożonej linii składu.

wprowadź opis obrazu tutaj

Wielość zakończenia asocjacji kompozycja jest w złożonej strony jest 1 lub 0..1, w zależności od tego, czy elementy mają obowiązek kompozytu (musi być przymocowana do kompozytowe), czy nie. Jeśli komponenty są nierozłączne , oznacza to, że mają obowiązkowy kompozyt.

2) Agregacja

Agregacja to kolejna szczególna forma skojarzenia z zamierzonym znaczeniem relacji część-całość, w której części całości można dzielić z innymi całościami. Na przykład możemy modelować agregację między zajęciami DegreeProgrami Course, jak pokazano na poniższym schemacie, ponieważ kurs jest częścią programu studiów i kurs może być dzielony między dwa lub więcej programów studiów (np. Stopień inżyniera może mieć wspólną literę C kurs programowania ze stopniem informatyki).

wprowadź opis obrazu tutaj

Jednak koncepcja agregacji z częściami, które można udostępniać, nie ma wielkiego znaczenia, więc nie ma to żadnego wpływu na implementację i dlatego wielu programistów woli nie używać białego diamentu w swoich diagramach klas, ale po prostu modelować proste skojarzenie zamiast. Specyfikacja UML mówi: „Precyzyjna semantyka współdzielonej agregacji różni się w zależności od obszaru aplikacji i projektanta”.

Wielość od końca stowarzyszenia agregacji jest na całej stronie może być dowolna liczba (*), ponieważ część może należeć do lub dzielone między dowolną liczbę całości.

Gerd Wagner
źródło
2
Kompozycja nie jest ściśle związana z cyklem życia, ale w większości rzeczywistych problemów cykl życia jest głównym czynnikiem motywującym do tworzenia lub agregowania. W swojej odpowiedzi zabezpieczyłem się, mówiąc, że cykl życia jest „często” powiązany, a nie zawsze powiązany. Dobrze jest zauważyć, że cykl życia nie jest wymagany, ale stwierdzenie, że widok jest „głównym problemem” i jest błędny (ładną, pogrubioną czcionką), wydaje mi się nieprzydatny i umniejsza wskazanie praktycznych aspektów użytkowania.
Chris Kessel
Definitywnie się z tym nie zgadzam. Rozważania związane z cyklem życia nie mogą być „głównym czynnikiem motywującym do tego, czy komponujesz, czy agregujesz”, ponieważ masz je w wielu przypadkach asocjacji niezależnie od tego, czy reprezentują jakiś rodzaj relacji części całości (agregacja lub kompozycja). Za każdym razem, gdy skojarzenie ma koniec z krotnością dolnej granicy większą niż 0, co odpowiada obowiązkowej właściwości odwołania, otrzymasz zależność cyklu życia.
Gerd Wagner
8

W kategoriach kodu, kompozycja zazwyczaj sugeruje, że obiekt zawierający jest odpowiedzialny za tworzenie instancji składnika *, a obiekt zawierający zawiera jedyne długotrwałe odniesienia do niego. Więc jeśli obiekt nadrzędny zostanie usunięty z odniesień i zbierany jako śmieci, to samo zrobi to dziecko.

więc ten kod ...

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

sugeruje, że element zamówienia jest składnikiem zamówienia - elementy zamówienia nie istnieją poza swoim zamówieniem. Ale obiekty Item nie są konstruowane w kolejności - są przekazywane w razie potrzeby i nadal istnieją, nawet jeśli sklep nie ma zamówień. są więc powiązane, a nie komponenty.

* nb kontener jest odpowiedzialny za instancjonowanie komponentu, ale może w rzeczywistości nie wywoływać nowego ... () samego siebie - to jest java, zwykle najpierw trzeba przejść przez jedną lub dwie fabryki!

Chris May
źródło
0

Ilustracje koncepcyjne zawarte w innych odpowiedziach są przydatne, ale chciałbym podzielić się inną kwestią, która okazała się pomocna.

Uzyskałem pewien przebieg poza UML do generowania kodu, kodu źródłowego lub DDL dla relacyjnej bazy danych. Tam użyłem kompozycji, aby wskazać, że tabela ma w moim kodzie klucz obcy nieprzekraczający wartości null (w bazie danych) oraz obiekt „nadrzędny” (i często „końcowy”), który nie dopuszcza wartości null. Używam agregacji tam, gdzie zamierzam, aby rekord lub obiekt istniał jako „sierota”, niepowiązany z żadnym obiektem nadrzędnym lub został „adoptowany” przez inny obiekt nadrzędny.

Innymi słowy, użyłem notacji kompozycji jako skrótu, aby zasugerować dodatkowe ograniczenia, które mogą być potrzebne podczas pisania kodu dla modelu.

erickson
źródło
0

Przykład, który mi się podoba: Skład: Woda jest częścią stawu. (Staw jest składem wody.) Agregacja: Staw ma kaczki i ryby (Staw skupia kaczki i ryby)

Jak widać, pogrubiłem „część” i „ma”, ponieważ te 2 wyrażenia mogą zazwyczaj wskazywać, jaki rodzaj połączenia istnieje między klasami.

Ale jak podkreślają inni, często to, czy połączenie jest kompozycją, czy agregacją, zależy od aplikacji.

Raj Rao
źródło
Ale czasami pewne terminy są niejasne. Na przykład klasa Person „ma” nazwę, więc jest wyświetlana jako Osoba ma relację agregacji z nazwą. W rzeczywistości jest to relacja kompozycji. Czemu? Kiedy obiekt Person niszczy, tak samo powinno być z nazwą. A określenie „imię jest częścią osoby” nie brzmi naturalnie.
Asif Shahzad
0

Tak trudno jest rozróżnić relację zagregowaną i złożoną, ale wezmę kilka przykładów, mamy dom i pokoje, tutaj mamy związek złożony, pokój jest częścią domu i życie w pokoju się zaczęło z życiem domowym i zakończeniem życia domu, gdy życie domu dobiegnie końca, pokój jest częścią domu, mówimy o kompozycji, jak kraj i stolica, książka i strony. Dla przykładu zagregowanych relacji, weźmy zespół i graczy, gracz może istnieć bez zespołu, a zespół to grupa graczy, a życie gracza może rozpocząć się przed życiem zespołowym, jeśli mówimy o programowaniu, możemy tworzyć graczy i po tym, jak stworzymy zespół, ale dla kompozycji nie, tworzymy pomieszczenia wewnątrz domu. Kompozycja ----> kompozyt | komponowanie. Agregacja -------> grupa | element

czytać
źródło
0

Ustalmy warunki. Agregacja jest metatermem w standardzie UML i oznacza ZARÓWNO kompozycję, jak i wspólną agregację, nazywaną po prostu współużytkowaną . Często nazywa się to niepoprawnie „agregacją”. To ZŁE, bo kompozycja też jest agregacją. Jak rozumiem, masz na myśli „udostępniony”.

Dalej od standardu UML:

złożone - wskazuje, że właściwość jest zagregowana w sposób złożony, tj. obiekt złożony jest odpowiedzialny za istnienie i przechowywanie złożonych obiektów (części).

Tak więc stowarzyszenie University to cathedras jest kompozycją, ponieważ katedra nie istnieje poza uniwersytetem (IMHO)

Precyzyjna semantyka agregacji współużytkowanej różni się w zależności od obszaru aplikacji i projektanta.

Oznacza to, że wszystkie inne skojarzenia można narysować jako wspólne agregacje, jeśli przestrzegasz tylko niektórych zasad własnych lub kogoś innego. Zajrzyj też tutaj .

Gangnus
źródło
0

Weź pod uwagę części ludzkiego ciała, takie jak nerki, wątroba, mózg. Gdybyśmy spróbowali odwzorować tutaj pojęcie kompozycji i agregacji, wyglądałoby to tak:

Przed pojawieniem się przeszczepów części ciała, takich jak nerki i wątroba, te dwie części ciała były w kompozycji z ludzkim ciałem i nie mogą istnieć w izolacji z ludzkim ciałem.

Ale po pojawieniu się przeszczepu części ciała można je przeszczepić do innego ludzkiego ciała, więc te części są agregowane z ludzkim ciałem, ponieważ ich istnienie w izolacji z ludzkim ciałem jest teraz możliwe.

Azfar Niaz
źródło