\

Školení Návrhové vzory, OOP a UML


 Sunday, 26 March 2006
UML - O agregaci, kompozici a asociaci a jako bonus společenská aktualitka :)

Na svých přednáškách při vysvětlování asociace a kompozice mám slide, na kterém jsou zmíněny základní rozdíly mezi oběma typy vztahů v UML. Ihned k tomu ale dodávám, že zmíněné rozdíly jsou akademické a že v praxi si vystačíme většinou s jedním typem vztahu (s agregací), u kterého při kódování intuitivně víme, zda složený (kompozitní) objekt rozhoduje, a pokud ano, tak v jaké míře, o životním cyklu svých konstituentů (objektů, z nichž je složen).

 

Kompozice
  • Kompozitní objekt nemůže existovat bez komponentních složek.
  • Každý komponentní objekt může být součástí jen jedné kompozice
  • Kompozice je většinou heterometrická
Agregace
  • Agregace může existovat bez svých konstitučních objektů
  • Jeden objekt může být potenciálně konstituentem více konstitučních objektů
  • Agregace inklinují k homeometrii

Informace o rozdílu mezi agregací a kompozicí vycházejí z UML specifikace, kde se říká:

"[Agregace je] speciální forma asociace, která specifikuje vztah mezi agregujícím(celkem) a jeho konstituentem (částí)."

"Kompozitní agregace je silnější forma agregace, která vyžaduje, že jakákoli instance konstituenta (části) bude součástí nejvýše jednoho kompozitního objektu. Jestliže je kompozitní objekt smazán, jsou většinou všechny jeho části vymazány s ním".

Čte někdo vůbec UML specifikaci namísto čtení takzvaně přístupných  a "lidsky psaných" knih, které dogmaticky vyžadují rozlišování mezi kompozici a agregací? Jak si můžete všimnout, v definicích agregace i kompozice je zřetelně vidět pozvolný přechod mezi asociací, agregací a kompozicí a ne žádné ostré hranice, jak se nám mnohdy snaží vsugerovat sekundární literatura k UML nebo žabomyší akademické války o přesný význam termínů. Převedu-li definice a jejich důsledky do normální řeči - agregace ani kompozice není z hlediska UML nic jiného než asociace. Protože se ale asociace s rysy kompozice a agregace vyskytují často,  zavedeme pro ně speciální jazykový konstrukty. Tyto jazykové konstrukty jsou implicitními nositeli omezení, jež jsou na agregaci a kompozici kladeny. Spory o to, co je v diagramu ještě agregace a co už musí být kompozice jsou směšné a nikam nevedoucí  - je to jen zvlášní druh moderního pseudovědeckého sektářství, kde se na hranici místo kacířů zástupně smaží nedogmatický duch UML.

Dále moje rozlišení agregace a kompozice vycházejí z praxe, kde indukcí dojdete k tomu, že kompozice bývá heterometrická  - konstituenti jsou objekty z různých tříd. Typicky například u faktury rozlišujete mezi řádky faktury, záhlavím faktury a zápatím faktury - faktura je tedy složena minimálně z objektů tří různých tříd. Když faktura nemá záhlaví, zápatí nebo alespoň jeden řádek, nemůže jít o fakturu. 

U agregace si častěji všimneme toho, že agregované objekty mohou být sdílené a že nezanikají se zánikem celku. Typicky o agregaci hovoříme třeba, když budeme modelovat kalendář pro obchodní zástupce a v kalendáři budou zadávány  jejich schůzky. Kalendář jako takový (seznam dní) může existovat i bez jakékoli evidované události. Některé události v kalendáři jsou privátní - typicky pravidelná návštěva přiděleného zákazníka. Jiné události jsou sdílené - společná schůzka všech obchodních zástupců je (přesněji řečeno - v tomto případě může být výhodně modelována jako) sdílená událost ve více kalendářích. I ty takzvaně privátní schůzky mohou "putovat" po kalendářích různých obchodních zástupců, když se dohodnou, že jeden po dobu dovolené zastoupí druhého a že převezme i jeho schůzky.

Důležité je si uvědomit, že v jazycích jako je C# nebo Java je rozdíl mezi kompozicí a agregaci opravdu zanedbatelný. Důvod je jednoduchý - nemáme v nich operátor delete([]) a odpovědnost za likvidaci objektů za nás převzal Garbage Collector. V C# a Javě si musíme pouze hlídat řízení životního cyklu objektů ukládaných do databáze - pokud něco (exkluzivně i sdíleně) vlastním (kompozice i agregace) , měl bych si uvědomit, že:

  1. Při zániku vazby musí dojít k odstranění objektu z databáze. Tedy odebere-li někdo řádek faktury z kolekce, je objekt faktura odpovědný za smazání vazby.
  2. Jestliže nemažu vazby fyzicky v databázi, ale pouze u objektů ze zrušených vazeb nastavuji stav 'neaktivní', musí moje business vrstva centrálně podporovat princip "co je neaktivní, je tabu a nikdo s tím nesmí pracovat  - a jak to v SW bývá, vždy máme výjimky. Jedinou výjimkou z tohoto pravidla jsou objekty, u nichž eviduji historii."

Poslední poznámka z praxe:

Na jedné přednášce (myslím před rokem na DNG) jsem se setkal s názorem, že typickým zástupcem agregace je "typování" objektů. Pod typováním objektu se můžeme představit objekt Uchazeč o práci, který má na sobě navázáno 0..n dalších objektů z třídy (z hlediska databáze z číselníku) Schopnost (řidičák, anglický jazyk, německý jazyk, práce s Excelem, lámání ženských srdcí atd.). Schopnost je zde termín, pod který jsou subsumovány všechny sledované typy evidovaných znalostí a dovedností. "Typování" není nic jiného, než klasifikace objektů dle různých kritérií, což nám umožňuje objekty rychle seskupovat do (z hlediska projektu) zajímavých množin - například budu-li obsazovat pozici lamačem srdcí se znalostí německého jazyka, snadno zjistím množinu uchazečů splňujících zadaná omezení.

Každý uchazeč může tedy "agregovat" o..n znalostí. Ale jde opravdu o agregaci? Já myslím, že je to prostá asociace - uchazeč nemá žádnou zvláštní vazbu na znalosti, ty jsou k němu jen "volně přidruženy".

A za jakých podmínek by bylo vhodné překvalifikovat vazbu mezi Uchazečem a Schopností opravdu na agregaci ? V momentě, kdy budete chtít evidovat nějakou dodatečnou a unikátní informaci k vazbě mezi uchazečem a jeho schopnostmi. Když tedy budeme chtít zjistit, od kdy uchazeč vlastní řidičský průkaz, nebo kolik dobytí ženských srdcí posloužilo jako předmostí k dobytí klínů;-) , zavedeme novou třídu DetailSchopnostíUchazeče - tato třída bude v asociaci s původní třídou Schopnost a bude agregována třídou Uchazeč (anebo dokonce v tomto případě bude jejím komponentním objektem) :-) .

Proč? Informace, které nesou objekty z třídy DetailSchopnostíUchazeče nemají význam "an sich", ale jen ve spojení s uchazečem. Jsou nedílnou částí právě jednoho obrazu, který nám dává objekt Uchazeč. Třída Schopnost nedílnou součástí obrazu právě jednoho Uchazeče nebyla - nenesla žádné specifické informace o uchazeči, jen s ním byla svázána náhodným poutem - asociací.

Na konec aktualitka na asociaci a kompozici ze života. :)

Asociace je pouhé registrované partnerství, ve kterém jsou dva konstituenti nahodilými objekty, kteří mají vůči sobě jeden kontingentní a zparchantělým parlamentem posvěcený link. Oba nijak závazně neřídí životní cyklus toho druhého.

Uzavřením manželství vzniká sakrální kompozitní objekt, jehož nedílnými součástmi jsou oba manželé s vzájemně protknutými životními cykly. A jak víme, při zániku kompozitního objektu, dříve či později nevratně odumírají i komponentní objekty.

I když nemusíme rozlišovat mezi asociací, agregací a kompozicí v UML, v životě může být dobře patrný rozdíl mezi asociací a kompozicí diferencujícím znakem mezi frivolní hrou a závazným svazkem. A pak že nelze do odborného blogu jednoduše a nenásilně propašovat názor na politická nebo společenská témata:-)



Sunday, 26 March 2006 15:50:53 (Central Europe Standard Time, UTC+01:00)       
Comments [5]  UML