Dzisiaj krótszy post i to trochę filozoficznej ;) natury.

Rysując model domenowy dla naszej aplikacji w postaci UML-owego diagramu klas natknąłem się na pewną zagwozdkę. Konkretnie dylemat dotyczył różnic pomiędzy asocjacją, kompozycją a agregacją. Czytając formalne opisy, sprawa wydaje się prosta. Wątpliwości pojawiają się  w przypadku wyboru pomiędzy asocjacją, a jej bardziej specjalizowanym kuzynem – agregacją. Agregacja zgodnie z  definicją reprezentuje asocjację typu „has a”. Jednak rysując już konkretny diagram wybór ten nie jest wcale taki oczywisty: człowiek „subskrybuje” czasopismo (asocjacja), czy też człowiek „ma subskrypcję na” czasopismo (agregacja) – przykłady i dyskusje można by mnożyć bez końca.

Co więcej różnica ta nie ma żadnego przełożenia na kod programu, gdyż zarówno asocjacja, jak i agregacja reprezentowane są w identyczny sposób. Gdzie więc narysować grubą czerwoną linię oddzielającą jedno pojęcie od drugiego, gdy nie dość że z semantycznego punktu widzenia sprawa jest mocno dyskusyjna, to dodatkowo jeszcze wybór takiego a nie innego rodzaju połączenia nie powoduje żadnego rozróżnienia w kodzie? Modelowanie nie powinno być sztuką dla sztuki i taki a nie inny model powinien mieć praktyczne odzwierciedlenie. Zdaje się, że w związku z takimi niejednoznacznościami, przez pewien czas planowano nawet usunąć pojęcie „agregacji” z UML 2.0, finalnie jednak tak się nie stało.

Z kompozycją sprawa jest już dużo prostsza, ponieważ ten rodzaj połączenia dodaje istotną informację, że pewien obiekt może istnieć wyłącznie jako część kompozycji i tym samym cykl jego życia jest zależny od cyklu życia obiektu-kontenera. W przypadku języków nie posiadających garbage collector-a, jak np. C++, będzie to oznaczało, że w trakcie niszczenia obiektu-kontenera, powinny być niszczone obiekty, które on zawiera. W przypadku nowocześniejszych języków, jak np. Java, C#, Python, itp. nie będzie to jednak już tak widoczne – ponieważ tam nie ma potrzeby „ręcznego” zwalniania pamięci.

Konkluzja

Pojęcie kompozycji wydaje się być dość jasno określone, co jednak z dylematem asocjacja vs agregacja? Tutaj skłaniam się ku sugestii Martina Fowler-a: nie używaj agregacji, dopóki nie masz naprawdę dobrego uzasadnienia :) .

Lektura uzupełniająca:

4 Comments

  1. Andrzej says:

    Na stronie http://www.wstt.edu.pl/pliki/materialy/pio/w4b.pdf (to materiały opracowane na podstawie wykładów prof. Subiety) czytamy:
    - Agregacja jest szczególnym rodzajem asocjacji wyrażającym zależność część-całość. Np. silnik jest częścią samochodu.
    - Nie istnieje jedna powszechnie akceptowana definicja agregacji. P. Coad podaje jako przykład agregacji związek pomiędzy organizacją i jej pracownikami; dla odmiany J. Rumbaugh twierdzi, że firma nie jest agregacją jej pracowników

    Chyba właśnie tak jest – nie ma jednoznacznej definicji. Moim zdaniem poza wyraźnymi relacjami całość-część lepiej nie stosować agregacji. Dokładnie tak jak piszesz w konkluzji :-)

  2. Przemek says:

    Dobrym przykładem na stosowanie rozróżnienia agregacja vs. asocjacja są opisy wzorców projektowych. Klasyk GoF – Composite – używa właśnie agregacji do wyrażenia zalażności część-całość – jeden rzut oka i ‘wiemy o co chodzi’.

    Skłaniam się ku konkluzji Mikołaja, że stosowanie tych pojęć wymaga bardzo elastycznego, a jednocześnie świadomego podejścia. Pamiętajmy jednak o tym, że modelowanie samo w sobie niekoniecznie zawsze przekłada się na implementację – jeśli agregacja daje nam możliwość uchwycenia czegoś ‘między wierszami’, jestem za jej stosowaniem.

  3. Michał Orzechowski says:

    Projekt powinień być taki, żeby osoby które z nim pracują patrząc na ten sam „rysunek” napisały ten sam kod ;-) . Jeżeli tak jest to dobrze. A czy będziemy „profesjonalni” i zrobimy to w UML poświęcając na stawianie „kresek” 3-4 tygodnie bo narzędzie którego używamy ma pewne wady i wolno nam idzie, czy nasmarujemy to mazakiem na tablicy i wszyscy którzy mają mieć obraz sytuacji zrozumieją o co chodzi – w moim przekonaniu, nie ma wiekszego znaczenia. Nie ma też znaczenia czy będzie tam agregacja czy asocjacja. Bo jeżeli ludzie wiedzą co mają zrobić, nie zmyli ich najgorszy projekt. A jeżeli nie wiedzą, to nawet najlepszy im nie pomoże :-) . Liczy się efekt końcowy. Od jakiegoś czasu wyznaję zasadę: działające oprogramowanie, ponad wyczerpującą dokumentację. Hmm skąd my to znamy ;-) ?

  4. Mikołaj Kmita says:

    @Andrzej, Przemek
    Dzięki za trafne uwagi i przykład – faktycznie przykład z Composite wnosi coś ‘między wierszami’, tj. informację o całość-część. Jednak w przypadku takiego Decorator-a, gdzie też została użyta agregacja nie jest to już tak oczywiste… – ale jest to wybitnie akademicki temat na długie zimowe wieczory.

    @Michał
    Dzięki za pragmatyczne spojrzenie na temat – choć może z tego postu tego nie widać, staramy się robić dokładnie to samo, tj. podchodzić pragmatycznie i nie obciążać się niczym, co nie wnosi dla nas realnej wartości (także jestem gorącym zwolennikiem podejść typu Agile/SCRUM). Choć jak widać powyżej, czasem moja dociekliwość bierze nad tym górę… ;)

    Gdybyśmy pracowali w tym samym pomieszczeniu, pewnie byłoby tak jak piszesz – duża biała tablica i namalowany pisakiem diagram, rodem z Agile. Jednak pracujemy osobno i tylko cyklicznie się spotykamy – a taki tryb wymaga trochę odmiennego podejścia.
    I nie było tak źle z opanowaniem narzędzia (w tym wypadku jest to StarUML) – zajęło to kilka minut. Dodatkowo modelujemy w ten sposób tylko część która mocno nas wszystkich dotyczy, czyli model domenowy – co doskonale upraszcza nam późniejsze dyskusje.

    Może za jakiś czas, gdy nasz „proces” okrzepnie na tyle, że będzie go można nazwać „procesem” ;) trochę go opiszemy, wraz z używanymi przez nas narzędziami.

    Literatura uzupełniająca:
    * Agile Tools. When is Whiteboard a Better choice than Software?
    * Using an Agile Software Process with Offshore Development – na szczęście większość kwestii opisanych tutaj nas nie dotyczy…

Leave a Reply