Vztah typu Extend v UML a jeho zvláštnosti © RNDr. Ilja Kraval 2007 Object Consulting s.r.o. http://www.objects.cz
[email protected] Do diskusního fóra na Pandoře (http://pandora.idnes.cz/conference/objcon/) přišel následující dotaz: Zdravim, rad bych si objasnil nasledujici vec. Vychazim z toho ze vazba Extend mezi dvema prvky UseCase vyjadruje podminene pouziti. Pokud je prvek A "extendovan" prvkem B a sipka je ve smeru od B k A. Prvek A je zavisly na B. Pokud jsou prvky v samostatnych packages pak package prvku B nemuze znat package prvku A. Proc to vlastne resim? Pokud v EA u packages zavedu rizeni verzi pomoci (napriklad Visual SourceSafe) a upravuji prvek A ktery ma byt extendovan prvekm B pak musim provest check out u package B. Coz se mi moc nelibi protoze B by melo byt jedno kdo ji pouziva. U Include to funguje spravne. Co si o tom myslite? Je to chyba v EA? Nebo spatne chapu vyznam Extend? Diky Marek B.
Zkusíme se tedy blíže podívat na specifikaci vztahu typu Extend. Uvedeme si, jak je definován přímo v UML. Avšak hned na začátku bych si dovolil drobně poopravit větu z dotazu: „…vazba Extend mezi dvema prvky UseCase vyjadruje podminene pouziti…" která je pravdivá pouze částečně. Navíc kromě existující podmínky extenze (v bodě nazývaném jako Extension Point) je třeba ještě dodat, že prvek typu Use Case, který rozšiřuje, má povahu nějakého rozšíření, tj. něco jako „přívěsek, dodatek“ k
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
rozšiřovanému prvku typu Use Case. Nejedná se tedy o klasické podmíněné „if … else“ ve smyslu toku v programování, ale o aditivní extenzi. Problém, o kterém se v dotazu píše, je již takříkajíc přímo v definici jazyka UML. Podívejme se přesně, jak je vztah typu Extend v UML přesně definován a rozeberme si jeho definici i s příkladem, který je ve specifikaci také uveden.
Poznámka: všechny texty ze specifikace UML jsou převzaty z dokumentu označeném jako „Unified Modeling Language: Superstructure, version 2.0 formal/05-07-04“, který je volně ke stažení na adrese http://www.omg.org/technology/documents/formal/uml.htm . K datu vydání tohoto článku se jedná o nejaktuálnější verzi specifikace UML staženou aktuálně z uvedené pozice.
Specifikace jazyka UML definuje vztah typu Extend takto (kapitola 16.3.3, překlad):
Vztah typu Extend Jedná se o vztah ve směru od rozšiřujícího prvku typu Use Case k rozšiřovanému prvku typu Use Case, který specifikuje jak a kdy bude chování rozšiřujícího prvku typu Use Case vloženo do rozšiřovaného chování prvku typu Use Case.
Všimněme si jedné velmi důležité okolnosti v textu definice. Hovoří se o vložení chování prvku rozšiřujícího (v textu dotazu označen jako prvek B typu Use Case) do rozšiřovaného (v textu dotazu prvek A typu Use Case). Znamená to, že dovnitř prvku A je vloženo chování prvku B a to nějakým specifickým způsobem (podmíněně) a tím prvek B za určitých podmínek rozšiřuje prvek A.
strana 2
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
Znázorníme si situaci ještě na obrázku:
A
«extend»
B
obrázek 1 Prvek B typu Use Case "extenduje", tedy rozšiřuje prvek A, ale chování prvku B je vloženo za určitých podmínek do prvku A Na obrázku je podle definice znázorněno, že prvek A je rozšiřovaný prvek typu Use Case, dále že prvek B je rozšiřující prvek typu Use Case a navíc podle definice obrázek znázorňuje, že chování prvku B je vloženo za určitých podmínek do chování prvku A. V další části popisu se lze dočíst ve specifikaci UML následující popis:
Popis Tento vztah specifikuje, že chování případu užití může být rozšířeno o chování dalšího (obvykle doplňkového) případu užití. Toto rozšíření se koná v jednom nebo více specifických bodech rozšíření definovaných v rozšiřovaném případu užití. Všimněte si nicméně, že rozšiřovaný případ užití je definován nezávisle na rozšiřujícím případu užití a je významově nezávislý na rozšiřujícím případu užití. Na druhé straně rozšiřující případ užití typicky definuje chování, které nutně nemusí být smysluplné samo o sobě. Rozšiřující případ užití definuje sadu modulárních přírůstků chování, což rozšiřuje průběh rozšiřovaného případu užití za nějakých specifických podmínek. Všimněte si, že tentýž rozšiřující případ užití může rozšiřovat více než jeden případ užití. Navíc rozšiřující případ užití může být dále rozšířen.
Zde si všimněme poněkud překvapivého tvrzení, že „…rozšiřovaný případ užití je definován nezávisle na rozšiřujícím případu užití a je významově nezávislý na
strana 3
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
rozšiřujícím případu užití…“ K tomuto bodu se ještě vrátíme, protože zde je uschováno jádro pudla našeho dotazu. Další částí specifikace vztahu Extend je vysvětlení sémantiky tohoto vztahu, což je velmi zajímavé:
Koncept "umístění rozšíření" (tj.- umístění bodu extenze) je úmyslně ponechán blíže nespecifikovaným, protože případy užití jsou typicky specifikovány v různých idiosynkratických formátech (pozn. překl.: různorodých a výstředních), jako je přirozený jazyk, tabulky, stromy, atd . Proto není snadné zachytit jeho strukturu přesně nebo obecněji nějakým formálním modelem. Intuitivní představu o umístění rozšíření si nejlépe můžeme vytvořit pomocí příkladu u textového popisu případu užití. Obvykle se případ užití s rozšiřujícími body sestává ze sady jemnějších granulovaných zlomků textových popisů chování, které jsou vykonány v sekvenci po sobě. Toto rozdělené členění textu případu užití umožňuje, aby původní popis chování byl rozšířen slučováním doplňkových fragmentů popisů chování ve vhodných místech vložení mezi originálními fragmenty (body rozšíření). Takto se rozšiřující případ užití (tj. ten, co rozšiřuje) typicky sestává z jednoho nebo více zlomků popisů chování, které jsou vloženy do vhodných bodů rozšiřovaného případu užití (tj. do toho, který je rozšiřován). Pokud je v době dosažení prvního lokace bodu extenze podmínka rozšíření "true", pak všechny odpovídající fragmenty chování z rozšiřujícího případu užití budou také vykonány. Pokud je podmínka "false", rozšíření nenastane. Jednotlivé zlomky jsou vykonány, jakmile jsou dosaženy odpovídající body extenze z rozšiřujícího případu užití. Poté, co je daný zlomek dokončen, exekuce pokračuje v chování rozšiřovaného případu užití následně po bodu rozšíření. Všimněte si, že třebaže jsou zapojeny vícenásobně případy užití , existuje pouze jediné chování běhu případu užití.
Nyní již můžeme učinit první závěry z těchto definic a vysvětlení. Jestliže jsme uvedený text uvedený v předešlém odstavci pochopili správně, potom je z hlediska vzájemného použití (kdo koho používá, neboli jak se píše v dotazu „kdo o kom ví“) evidentní, že případ užití A, který je extendován, používá případ užití B, který jej extenduje a to tak, že existuje nějaká podmínka, která pokud je splněna, tak v odpovídajících bodech „odskoku“ se provedou fragmenty případu užití B (jak vyplývá z textu, nemusí se jednat pouze jeden fragment!). Z hlediska chápání závislosti v tomto pojetí, tj. kdo koho používá, je evidentně A závislé na B, protože v A musíme v textu definovat body „odskoku“ a definovat, že v těchto bodech se jedná o konkrétní vykonání případu užití B. Jinak řečeno, ten, kdo strana 4
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
píše text v případu užití A, se v tomto textu evidentně nějak odvolává na případ užití B. Co se týče toho, jak je závislost vysvětlena ve specifikaci UML, tj. píše se, že případ užití A je nezávislý na případu užití B, tak zde se zřejmě má na mysli ta skutečnost, že případ užití A je významově nezávislý na B, tj. jeho sekvence textů v A funguje nezávisle na tom, zda „bude zapnuta“ nebo „nebude zapnuta“ extenze a vložené aditivní fragmenty se uskuteční nebo ne. Fragmenty jsou pouze „doplňkem navíc“, tj. doplňkovou extenzí případu užití A a neovlivňují tak původní funkcionalitu definovanou bez vložení. K tomuto důležitému bodu se ještě vrátíme. Uveďme si příklad, který je uveden přímo ve specifikaci UML:
Condition: {customer selected HELP} extension point: Selection
Perform ATM Transaction Extension points: Selection
«extend»
On-Line Help
obrázek 2 Příklad na vztah typu Extend uvedený přímo ve specifikaci UML Ve specifikaci UML je tento diagram vysvětlen takto (doslovný překlad z originálu):
V diagramu nahoře případ užití „Perform ATM Transaction" má svůj extension point (bod rozšíření) "Selection". Tento případ užití je extendován přes tento extension point případem užití „On-Line Help“ vždy tam, kde se běh případu užití "Perform ATM Transaction" vyskytne v umístění onoho bodu extenze „Selection“ a zákazník přitom vybere klávesu Help. Všimněte si, že případ užití „Perform ATM Transaction" je definován nezávisle na případu užití „On-Line Help“.
strana 5
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
Tolik doslovný překlad. Co se týče poslední věty, je třeba ji opět chápat tak, že má význam v tom smyslu, že funkcionalita případu užití „Perform ATM Transaction" je pouze rozšířena v bodě extenze a tedy původní funkcionalita není rozšířením ovlivněna a je pouze doplněna. To je však je pouze logika věci ve smyslu vložení aditivní funkcionality a nikoliv otázkou změnového řízení. Pokud totiž vložíme aditivní funkcionalitu, tak samo toto vložení musí nutně vést k „překopání“ původního případu užití aspoň tím, že musíme do něj vložit bod extenze a v textu definovat uvedené „odskoky extenze“ (uvedené fragmenty textů) v daných bodech toku případu užití. Změnové řízení a práce se systémem pro řízení verzí podléhá složitějším zákonitostem . Představme si, že máme dvě funkcionality ve dvou modulech (resp. ve dvou prvcích typu Package), a nechť první funkcionalita F1 v prvním modulu (v prvku Package) volá druhou funkcionalitu F2 v druhém modulu (v druhém prvku Package). Pro názornost si klidně můžeme představit, že se jedná o funkce nazvané jako F1 a F2 ve dvou modulech. Stejně tak si můžeme představit dva případy užití ve dvou prvcích typu Package. Pro „check out“ může nastat hned několik variant podle toho, co vlastně měníme: 1. Pokud měníme funkci F1 (volající) a to bez změny funkce F2, potom nemusíme provést „check out“ modulu u funkce F2, ta se totiž nemění. 2. Pokud měníme funkci F2 uvnitř bez změny rozhraní této funkce (tj. funkce F1 nepocítí žádné změny), potom nemusíme provést „check out“ modulu u volající F1. 3. Pokud měníme F2 a měníme rozhraní, musíme „překopat“ všechny funkcionality, které tuto funkcionalitu volají (používají) včetně F1 a tedy musíme provést „check out“ modulu s funkcí F1. Podobně tomu bude i v případech užití. Zkusme si předešlý příklady na uvedeném diagramu s transakcí na bankomatu rozvést jakoby dále do další přesnější podoby i se specifikací textů a budeme si všímat, jak se oba případy užití chovají vzhledem ke změnovému řízení. Vyjděme tedy z uvedeného diagramu, kdy případ užití „Perform ATM Transaction" je extendován o případ užití „On-Line Help“ (viz předešlý obrázek). Připomenu, že pod tímto obrázkem je také vysvětlení tohoto diagramu. Nechť navíc platí, že případ užití „Perform ATM Transaction" je v jednom prvku typu Package a druhý případ užití „OnLine Help“ je v druhém prvku typu Package. Jak budou vypadat operace „check out“? První varianta je, že se změní funkcionalita extendovaného případu užití „Perform ATM Transaction", aniž by to ovlivnilo poskytovaný help, například se jedná o opravu nějaké drobnosti bez zásahu do helpu. V tom případě by se teoreticky měl provést strana 6
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
„check out“ pouze u prvku Package prvního extendovaného případu užití „Perform ATM Transaction" a logicky vzato by se na prvek typu Package případu užití „OnLine Help“ nemusel vůbec použít „check out“, protože se tento případ užití nemění. Druhý případ odpovídá situaci, kdy se něco změní „uvnitř helpu“, ale případ užití „Perform ATM Transaction" toto nepocítí. Jako příklad bychom mohli uvést opravy chybných anebo nepřesných textů v helpu bez změny logiky helpu. V tom případě stačí provést „check out“ prvku typu Package s případem užití „On-Line Help“. Třetí případ svědčí o tom, kdo je na kom závislý z hlediska použití. Představme si, že help funguje tak, že při jeho vyvolání se nějak přebere název kroku (realizace v designu například přes vstupní parametr, pomocí globální proměnné apod.), kde se právě v toku případu užití zákazník nachází (názvy kroků jsou například „zasunutí karty“, „zadání pinu“, „výběr jazyka“ atd.). Text v rozšiřovaném případu užití „Perform ATM Transaction" vypadá potom nějak takto: Use Case Scenario Perform ATM Transaction ... ...a zákazníkovi se nabídne zadání PIN. Vsunuto via Extension Point Selection Pokud zákazník vyvolá Help, nastaví se název kroku na „zadání PIN“ a vyvolá se Help (viz extend od UC On-Line Help) Konec vsunutí via Extension Point Selection Zákazník zadá PIN, provede se verifikace zadaného čísla PIN vůči kartě, pokud nesouhlasí...(atd.) ... Takovýchto „vsuvek“ je v textu více pro každé vyvolání helpu s různým názvem kroku v různých částech původního scénáře. Tyto vsunuté texty neovlivňují původní funkcionalitu, jsou to pouze vsuvky do původní funkcionality. Jak vidět, tak v tomto příkladu se uvnitř případu užití „On-Line Help“ pracuje s převzatým názvem kroku a podle něj se vyvolává odpovídající část helpu, například přes klasický „switch“. Pokud však „překopeme“ případ užití „On-Line Help“ tak, že nebude pracovat s „názvem kroku“, ale změníme tento parametr například na „číslo kroku“, potom budeme díky této změně muset předělat také případ užití „Perform ATM Transaction" a tato změna se pochopitelně projeví až do úrovně abstrakce programování. V tomto ohledu je případ užití „Perform ATM Transaction" na případu užití „On-Line Help“ samozřejmě závislý! Závěry Z uvedených tří příkladů na „check out“ prvků typů Package s uvedenými případy užití ve vztahu Extend je zřejmé, že vztah Extend neznamená vskutku „totální nezávislost“ extendovaného případu užití A na extendujícím případu užití B (tj. nezávislost ve smyslu „kdo koho používá“). Jedná se pouze o nezávislost strana 7
Vztah typu Extend v UML a jeho zvláštnosti © Ilja Kraval, 2007, http://www.objects.cz
významovou, tj. o aditivní vsunutí částí funkcionalit neměnící kostru běhu extendovaného případu užití (jako vsunuté „odskoky“). Osobně se domnívám, že z uvedeného vyplývá, že pro řízení verzí při modelování nemusí platit automatická logika „co check out a co ne check out“. Je otázkou, zda je tedy vždy vhodné se opřít o již zabudované funkcionality v nástrojích, nebo zda je lepší provádět tyto a podobné operace s nástrojem pro řízení verzí ručně anebo zda není ještě lepší napsat si svou vlastní jednoduchou utilitu podle vlastních potřeb. Konec dokumentu
strana 8