Kdy použít v Use Case Diagramu vztah Extend a kdy Include (část 1)

V mnoha školeních a konzultacích jsem takřka pokaždé narazil na rozepře mezi vývojáři o nasazení vztahu Extend. Jak se má tento vztah používat správně a korektně?

Základní problémy tohoto vztahu spočívají v následujících třech bodech:

  1. Vztah Extend působí takříkajíc v „obráceném garde“
  2. Vztah Extend se používá ve velmi specifické situaci a pro velmi specifický účel. Dokonce pokud tato specifická situace nenastane, nesmí se použít a musí se nasadit vztah Include.
  3. Vztah Extend je v technologii realizován zvláštními technikami programování a analytik musí mít dobrou představu o tom, jak může být vztah Extend realizován v programu přímo technologicky, jinak má problém s jeho pochopením.

Interakce “v obráceném garde”

Nejprve si vysvětlíme první bod, tj. co to znamená, že vztah působí „v obráceném garde“.

Zaveďme dva případy užití, např. A a B, a mezi nimi vztah Extend např. takto:

 

 

Interakce je zde pro názornost a úmyslně namalována „zprava doleva“. Směr závislosti odvozený od směru tohoto vztahu je dán směrem šipky tohoto vztahu, tj. od B k A, tedy případ užití B potřebuje A, ale případ užití A nepotřebuje B. Případ užití B je zde v roli jako tzv. „extendující“, případ užití A je v roli tzv. „extendovaný” .

Okolí těchto dvou případů užití používá případ užití A, nikoliv případ užití B, např. takto:

 

clanek include extend 2

 

Dobrá představa je, že extendující případ užití B je nějak „zaháčkován“ k extendovanému případu užití A (aniž by to A věděl) a bude nějakým zvláštním způsobem z A vyvolán, tj. použit. K tomuto bodu se ještě vrátíme v dalším výkladu.

Kdy se Extend používá

Základní vlastností interakce Extend je zmíněný směr závislosti, tj. skutečnost, že okolí (např. Actor X) přistupuje k extendovanému případu užití A jako k nosnému, hlavnímu případu užití (ten potřebuje použít) a tento „nějak vyvolá“ použití extendujícího případu užití B, o kterém on sám neví.

Vztah Extend se zásadně používá pouze a jenom tam, kde je tento směr vazby od B k A takto vyžadován a nikde jinde. Protože případ užití A neví nic o případu užití B (a přitom jej vyvolává), lze přidávat další a další extendující případy užití bez zásahu do případu užití A a takto se žádá, aby byl také navržen i program. Tyto situace nastávají např. při nasazení událostí (vzor OBSERVER, LISTENER, delegáti apod.), nebo u flexibilně přidávaných aditivních funkcionalit (vzor COMMAND) apod. V jiných situacích, kdy případ užití A přímo oslovuje případ užití B a používá jej „natvrdo“ (a tedy je na něm závislý) se tento vztah nesmí použít, zde je třeba nasadit správně vztah Include. Pro posouzení, zda použít vztah Extend nebo vztah Include, je tedy rozhodující směr závislosti ve vztahu obou případů užití.

Příklad chybného použití vztahu Extend

Představme si scénář nějakého případu užití UCX, ve kterém se ze zobrazeného seznamu osob vybírá osoba, přičemž pokud uživatel v seznamu osobu nenajde, může do systému založit novou osobu pomocí vyvolání případu užití Založení nové osoby přímo z tohoto případu užití a tím ji přidat do seznamu osob. Mnohdy autoři tuto situaci (resp. podobné) malují jako Extend, což je chybně, protože směr závislosti je přesně naopak, než Extend vyžaduje. V tomto případě se jedná o přímé použití, tj. případ užití UCX natvrdo a přímo použije případ užití Založení nové osoby. Závislost je evidentně ve směru od UCX k Založení nové osoby, nikoliv naopak, a patří sem tedy správně vztah Include a nikoliv Extend.

V příštím pokračování článku se dovíme, jak se Extend používá přímo na ukázkovém příkladu konkrétně i s postupem v EA a poukážeme na další chybná použití vztahu Extend resp. doporučené alternativní použití vztahu Generalizace

pokračování následuje

 
Categories

About the Author:

správce a majitel Serveru objektových technologíí http://www.objects.cz

4 Comments
  1. David Hlaváč

    Dobrý den,

    díky za tento článek. Z mojí praxe mohu jen potvrdit, že vazba EXTEND opravdu způsobuje nekonečné diskuze a spekulace o tom, k čemu vlastně slouží.

    Mé interpretaci této vazby, která jestli vnímám správně je stejná té Vaší, pomohl pohled přes potřebu modularizace systému.

    Vyvíjíme systém, který je sdílen více zákazníky, čili aplikujeme sdílený vývoj a máme potřebu umět sestavovat instance daného systému tak, aby některé funkcionality byly zahrnuty a některé ne – například/zejména podle toho, co je nebo není pro business daného zákazníka z pohledu funkčního katalogu systému relevantní.

    Funkcionality jsou zahrnuty v nějakých modulech (“věcných” celcích) a ty jsou nebo nejsou do dané instance systému zahrnuty.

    Když si vezmu Váš příklad, tak řekněme, že UC A bude z modulu M1 a UC B bude z modulu M2. Pokud by mezi nimi existovala vazba z A do B typu INCLUDE, pak by nemohl být modul M1 nasazen bez modulu M2, protože UC A nemůže existovat bez UC B.

    Díky vazbě EXTEND ale můžeme pohodlně nasadit modul M1 bez modulu M2, protože UC A o UC B nic neví a k životu ho nepotřebuje.

    Nějaký obecný konkrétní příklad – čerpání úvěru jako událost 1, na základě čerpání úvěru má být generován nějaký úkol pro obchodního zástupce. Rozhodně dva moduly, jeden do oblasti úvěrů, druhý do oblasti řekněme podpory prodejní sítě. Pokud bych do UC pro provedení čerpání úvěru dal přímo volání vytvoření úkolu pro OZ, pak nejsem schopen sestavit instanci systému s úvěry bez podpory prodejní sítě.

    Pravdou ale je, že užití této vazby je naší v praxi minimální. Důvodů bude jistě víc.

    Pěkné Vánoce a do nového roku hodně pracovních i nepracovních úspěchů, hodně štěstí.

  2. Děkuji za příspěvek – přesně tak!
    Váš příklad úzce souvisí s kapitolou Modulární nůžky v knize AM na našem serveru a souvisí s nejčastější chybou návrhu, jak se tyto modulární nůžky znemožní (špagetový resp. makarónový efekt kódu, kdy nakonec vše souvisí se vším, molochální systém).
    V situaci, kterou popisujete, je třeba nasadit některou z variant OBSERVERU, tj. buď LISTENER (Java) anebo události a delegáty (C#), anebo pokud se jedná o datově zaměřený systém, tak nějaké události přímo v databázi.
    V dalším pokračování si uvedeme příklad, který je velmi blízký tomu vašemu a současně si ukážeme variantu řešení s Generalizací (kterou upřednostňuji).

  3. Karel Richta

    Dobrý den, přečetl jsem si Váš článek “Kdy použít v Use Case Diagramu vztah Extend a kdy Include, 2. část” a trochu mne zarazil Váš komentář na konci: Příklad chybného použití vztahu Extend, kde pro případ prohlížení seznamu osob můžeme vyvolat případ užití “Založení nové osoby”. V článku tvrdíte, že se jedná o vztah “Include” nikoliv “Extend”. Měl jsem představu, že rozdíl mezi “Include” a “Extend” je “musí” a “může”. Tj. případ užití “Založení nové osoby” může, ale nemusí být použit a je to tedy vztah typu “Extend” – rozšiřuje možnosti prohlížení seznamu. Vztah “Include” by naznačoval nutnost vložení nové osoby?

0 Pings & Trackbacks

Leave a Reply