Druhá část odpovědi na mail ohledně zpracování případů užití Autor RNDr. Ilja Kraval leden 2008 www.objects.cz Úvod Tento článek navazuje jako pokračování na článek předešlý. Minule jsme si vysvětlili, jak lze jednoduše a efektivně zavádět pojmy (user concepts) v případech užití a jak je dobré mít i technickou podporu výkonného editoru umožňující zavést odkazy na tyto pojmy (viz produkt EA Object Editor, http://www.objects.cz/eaoe/eaoe.html). Odpovíme si nyní na druhý dotaz v mailu: 2. Další často probíranou záležitostí je, jak pojmout situaci, kdy po ukončení nějaké funkcionality, popisované jedním Usecase, je bezprostředně spuštěna (buďto automaticky nebo manuálním zásahem uživatele) funkcionalita popisovaná jiným UseCase. Například ihned po ukončení UseCase Založit žádost následuje vždy UseCase Vytisknout žádost, jehož obsah ale nemůže být součástí UseCase Založit žádost, protože tisk žádosti se provádí nejen po jejím založení ale i v jiných dalších případech a tak je existence samostatného UseCase pro popis tisku žádosti zcela oprávněná. Jakým způsobem tedy předat designerovi informaci, že vždy po provedení Usecase Založit žádost je nutné provést UseCase Vytisknout žádost? Strana 1
Dokážu si představit tři různá řešení, z nichž první dvě mi přijdou jako špatná. - První možnost je že informaci o tom že na sebe oba UseCase navazují, nijak v modelu nezaznamenám a tím pádem jí ani nepředám. - Druhá možnost je propojit oba Usecase tak, že UseCase Založit žádost by jako poslední bod svého hlavního scénáře obsahoval include Usecase Vytisknout žádost. Ovšem takto pojaté UseCase diagramy by pak byly naprosto nepřehledné a plné změti vazebních čar. - Třetí a mnou preferovaná možnost, je zaznamenat úspěšné ukončení UseCase Založit žádost jako jeden z několika možných Starting events UseCasu Vytisknout žádost. A jako jednoho z primárních Actorů UseCase Vytisknout žádost zařadit i System, nebo System event (protože o Actora Time respektive Time event se v tomto případě nejedná). Jaký je váš názor na mnou navrhované řešení? Rozbor nedoporučených variant Uvedenou první variantu v modelu vůbec tuto skutečnost neuvádět ihned zavrhneme. Držíme se totiž základního pravidla, které zní: Co není v USE CASE modelu, to se neprogramuje!. Vynechat něco v případech užití znamená vlastně požadavek prosím neprogramovat, což určitě není dobře... Třetí variantě, kdy použijeme tzv. události, tak té bych se osobně raději vyhnul. Mechanismus událostí lze v modelu případu užití efektivně a s velkou výhodou zavést (mimochodem opravdu dobrý námět pro další článek!), ale slouží k úplně jinému účelu! Události a jejich zpracování v USE CASE modelu používáme tam, kde se má vyvolat dopředu neznámý počet zatím díky vývoji a díky novým verzím dopředu neznámých funkcionalit na určitou službu události. Tyto funkcionality (případy užití) se pomocí jednoduchého mechanismu přes generalizaci zaháčkují k dané události a jsou poté při vyvolání události obslouženy (jedná se o use case variantu vzoru OBSERVER - LISTENER). Pro vysvětlení mechanismu událostí v USE CASE modelu bych jako příklad uvedl část scénáře případu užití Zaúčtování převodního příkazu : Na začátku scénáře těsně před zaúčtováním se má obsloužit dopředu neznámý počet funkcionalit, což znamená, že se budou postupně s vývojem rozšiřovat a neznáme je proto přesně dopředu. Pokud chceme korektně tuto situaci namodelovat, neměli bychom použít přímé oslovení a vyvolání seznamu daných funkcionalit například nazvaných U1, U2, U3 nějak takto:...a dále se provede U1, U2, U3.... To Strana 2
je špatné řešení (i když funkční), protože seznam se bude s vývojem a s novými verzemi a novými moduly rozšiřovat. Například za půl roku přidáme modul Úvěry a v něm budeme také potřebovat vyvolat funkcionalitu (nazvěme pro názornost např. U4) jako reakci na událost před zaúčtováním převodního příkazu. V tomto špatném řešení musíme otevřít případ užití Zaúčtování převodního příkazu a přidat do něj další řádek a zavolat U4. Všimněte si, jak je to paradoxní a proti zdravému selskému rozumu a tedy indikace chyby: Přidáním nového modulu Úvěry musíme otevřít starý případ užití Zaúčtování převodního příkazu a změnit jej! Správné řešení je v obdobě vzoru OBSERVER: Musíme tyto funkcionality oslovit nepřímo přes polymorfismus, tj. pomocí generalizace v USE CASE modelu takto: Zaúčtování převodního příkazu «include» * Reakce před zaúčtováním U 1 U 2 U 3 obrázek 1 Příklad na využití mechanismu událostí v UC modelu (obdoba vzoru OBSERVER - LISTENER) Poznámka: Podrobněji pojednáme o tomto efektivním mechanismu v některém z dalších článků. Zde si pouze všimněme následujících důležitých skutečností: 1. Případ užití Reakce před zaúčtováním je abstraktní 2. V textu scénáře Zaúčtování převodního příkazu se odvoláváme na tento vrchní abstraktní případ užití ve stromu generalizace, ale realizují se, v tomto vzoru cyklem, konkrétní dědicové vždy po jednom. Technicky je to možné, protože v generalizaci platí tzv. zástupnost zespodu nahoru (do předka je dosazen potomek). Text ve scénáři je tedy napsán nějak takto:...dále se provedou všechny reakce před zaúčtováním, viz UC Reakce před zaúčtováním... (nejlépe pomocí odkazu v EA Object Editoru). Tím se vyvolávají dědicové. Strana 3
3. Přidat novou reakci (například s novým modulem Úvěry) vůbec neznamená překopat případ užití Zaúčtování převodního příkazu. Text scénáře se totiž již nemění, viz předešlý odstavec, kde věta...dále se provedou všechny reakce před zaúčtováním, viz UC Reakce před zaúčtováním... se nezmění. Analytik pouze přidá nového dědice (například U4) abstraktního případu užití Reakce před zaúčtováním. V každém případě bych použití událostí pro naše řešení zavrhl. Je zřejmé, že se totiž u nás evidentně nejedná o událostní problém. V okamžiku vystavování žádosti na konci scénáře je totiž zřejmé, že se má (i když třebas volitelně) vyvolat tisk žádosti a nepotřebujeme zavádět obdobu vzoru OBSERVER LISTENER s oslovením anonymních funkcionalit schovaných polymorfismem za předka. Zavedení událostí je tedy ve vašem případě něco navíc, něco, co zbytečně zesložiťuje a znepřehledňuje problém. Mechanismus událostí (obdoba vzoru OBSERVER) je v USE CASE modelu sice velmi efektivní, ale pokud se použije tam, kde nemá být použit (tj. tam, kde je jasné a dopředu dané, jaké funkcionality se mají vyvolat), potom výrazně zvyšuje nepřehlednost modelu, protože čtenář modelu vyhledává zbytečné vazby přes události. Celá konstrukce vyvolání případů je nelogicky skryta do vztahu k událostem. Nakonec ještě připomenu, že problematiku událostí v USE CASE modelu považuji za natolik důležitou, že se jí budu určitě věnovat v některém z příštích článků. Hádanka pro čtenáře Avšak problém dotazu je v našem příkladu úplně jinde. Zakopaný pes je skryt v této větě:...například ihned po ukončení UseCase Založit žádost následuje vždy UseCase Vytisknout žádost, jehož obsah ale nemůže být součástí UseCase Založit žádost, protože tisk žádosti se provádí nejen po jejím založení ale i v jiných dalších případech a tak je existence samostatného UseCase pro popis tisku žádosti zcela oprávněná... V každém případě autorovi musím z celého srdce poděkovat, protože touto větou nám připravil velmi dobrý příklad (kterou bych sám jako příklad nikdy nevymyslel!) pro ověření vlastních schopností správně modelovat. Máme zde nyní předložen opravdu záludný chyták! V této větě je totiž ukryta velmi vážná chyba! Vidíte ji? Otázka tedy zní: V čem je opravdu vážná chyba této věty? Strana 4
Zkusme tuto situaci chápat jako opravdu dobré cvičení a zvolme si tuto otázku jako test a hádanku pro čtenáře! Samozřejmě brzy (tj. asi v řádu 14 dnů) vyjde pokračování tohoto článku i s odpovědí, ale zkuste, pokud chcete, odpovědět na tuto otázku mailem na adresu objects@objects.cz! Najděte chybu v uvedené větě z mailu, vysvětlete podstatu této chyby a pošlete mi mail! Mimochodem, pro ty z vás, kteří již absolvovali naše školení OOP a UML (blíže viz zde), bude nalezení této chyby snadné. Napovím pouze, že se jedná o první a základní kapitolu školení, tedy o základní objektové paradigma v modelování, neboli o vnější všeobsahující pohled a vnitřní implementační pohled na prvky při modelování, jinak řečeno na školení stále se opakující červená niť číslo jedna! Těším se na vaše odpovědi, pište na adresu objects@objects.cz!...článek bude pokračovat! Strana 5