\

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


 Tuesday, April 18, 2006
Zajímavý dotaz (hádanka) na případy užití v UML - vztah Include, Extend, anebo ...?

Po základní analýze jste zjistili, jak zákazníci vašeho klienta vytvářejí objednávky:

"Zákazník v našem obchodě vybírá zboží a poté si může vybrat, jak jej uhradí. Jedním z možných typů platby je platba kartou. K založení objednávky dojde pouze tehdy, pokud zadané údaje o platební kartě jsou platné, zákazník má dostatečnou hotovost na účtu a platba tedy projde."

Řekněme, že z těchto údajů vytvoříme (kromě dalších, zde nezmiňovaných) dva případy užití:

  1. UC001 - Založení objednávky zákazníkem
  2. UC002 - Platba kartou

Jaký vztah je podle UML mezi těmito případy užití ? Odpověď není tak jednoduchá, jak se může na první (a dokonce i druhý a ležérní třetí) pohled zdát... :-)



Tuesday, April 18, 2006 9:27:39 AM (Central Europe Standard Time, UTC+01:00)       
Comments [27]  Programátorské hádanky | UML


Tuesday, April 18, 2006 12:08:05 PM (Central Europe Standard Time, UTC+01:00)
část pro platbu "vytrhnout" do nového usecase např. UC003; vztah UC001 -- UC003 bude include; vztah mezi UC002 a UC003 bude generalizace-specializace; vztah mezi UC001 a UC002 nebude žádný (jen zprostředkovaný pře UC003); řešení můžu zdůvodnit (ale asi chceš, aby si lámali hlavu i ostatní čtenáři :-)
Tuesday, April 18, 2006 12:10:54 PM (Central Europe Standard Time, UTC+01:00)
Zdůvodění takového řešení si rád poslechnu :)
Wednesday, April 19, 2006 8:05:13 AM (Central Europe Standard Time, UTC+01:00)
IMHO tak jak je to zadáno, případ UC002 by měl být rozšířen případem UC001. Include to být asi nemůže, protože UC001 by se provádělo vždy, což podle zadání není pravda. Rozšiřující UC001 se provádí jen tehdy, pokud jsou splněny určité podmínky ověření karty (viz zadání). Ale přijde mi to nějak proti srsti, protože rozšiřující UC bývá většinou tak nějak "menší" (často nemá ani samostatně smysl), volá se spíše jako výjimka než pravidelně (tady se naopak výjimečně nevolá).
pavel s
Wednesday, April 19, 2006 8:17:51 AM (Central Europe Standard Time, UTC+01:00)
testetest
Wednesday, April 19, 2006 8:24:01 AM (Central Europe Standard Time, UTC+01:00)
pavel s: Diky za reakci. zajimava myslenka :)

Co se tyce odeslani spotu - kdyz zadate PLATNY mail, tak by nemel byt zadny problem. Maily se sami koduji do tvaru "pavsykAT NOSPAMcentrum dot cz", takze nemusite mit obavy ze spammeru.
A dale musi byt spravne opsana captcha
Wednesday, April 19, 2006 8:24:06 AM (Central Europe Standard Time, UTC+01:00)
Souhlasim s pavex2. Je tam jeden include a jeden gen-spec.
Wednesday, April 19, 2006 9:15:45 AM (Central Europe Standard Time, UTC+01:00)
pavus, martin: udělat UC "platba" (nebo spíše "zaplatit") a mít UC "zaplatit kartou" jako jeho specializaci se sice nabízí, ale je tam opravdu vhodný vztah gen-spec? Já osobně gen-spec v případech užití nerad používám, protože tomu pak nikdo (kromě mne) nerozumí. Když si představím scénáře platby kartou, platby fakturou a platby za hotové, tak se mi zdá, že jsou až příliš odlišné pro společného předka a gen-spec.
pavel s
Wednesday, April 19, 2006 12:42:23 PM (Central Europe Standard Time, UTC+01:00)
to pavel s : určitě se mnou nebudou mnozí souhlasit, ale :
1. gen-spec mezi jednotlivými use-cases také prakticky nepoužívám (kvůli čtenářům na straně zákazníka); v podstatě ani extend nepoužívám - stačí už to, že zákazníkům musím vysvětlit gen-spec pro actory (tam je dědičnost opravdu užitečná); přitom <<include>> je celkem schopen pochopit i neinformatik
2. scénáře platby kartou/fakturou/za hotové vidím naopak jako (z hlediska chování) velmi podobné - vždy jde o to, aby zákazník definoval "jak bude platit", jen někdy zadává číslo karty (a systém ověří platnost a hotovost), někdy fakturační údaje (+ třeba ověření validní adresy/IČO), někdy "za hotové" (+ třeba generování úkolu pro telefonistu, aby ověřil objednávku); v případě tří samostatných use cases : chybí mi jakýsi "předek" kam můžu popřípadě v budoucnu dodefinovat fukčnosti týkající se všech tří způsobů plateb (ale netýkající se vyloženě tvoření objednávky)
Wednesday, April 19, 2006 1:55:17 PM (Central Europe Standard Time, UTC+01:00)
to pavus: Sice si také umím představit společnou funcionalitu (např. zadání kódu ze slevového kupónu), ale stejně mi to nějak nejde dohromady. Zadání (a ověření) fakturačních údajů je IMHO něco úplně jiného než zadání (a ověření) čísla karty dle zadání. To by pak mohl být předkem případ užití "zadat cokoliv", kde by se zadalo a ověřilo cokoliv - třeba login do systému.


Když vezmu zadání doslova, tak ty dva UC můžeme považovat za úplně nezávislé. Poslední věta zadání říká: "K založení objednávky dojde pouze tehdy...když platba projde". Tomu rozumím tak, že se provede nejprve UC002 a po jeho úspěšném dokončení se teprve začne provádět UC001. Takže se musím zeptat zákazníka: "Co to vlastně znamená, že platba projde? Rozumím tomu správně"

Wednesday, April 19, 2006 2:36:12 PM (Central Europe Standard Time, UTC+01:00)
pavel s:
Mate samozrejme se svoji otazkou na zakaznika pravdu.

Uvazujte tedy takto:
Plati, že kdyz zakaznik vybere zbozi, musi vybrat typ platy.
Kdyz plati jinak nez kartou (treba "na dobirku"), dojde k zalozeni objednavky a zadna validace platby neni potreba. Kdyz zvoli platbu kreditni kartou, musi obchodnikovi prijit informace, ze platba prosla a teprve pote povoli zalozeni objednavky s vybranym zbozim. To znamena, ze scenar UC001 je vzdy prvni - nejprve zadate vsechny informace k zalozeni zakazky a pak vyberete typ platby.
Kdyz platba kreditni kartou neprojde, musite dovolit vybrat jiny typ platby.

Samozrejme diskutujte - snad tak do tydne sem napisu clanek o vztazich Include a Extend a o omezenich a pastech Use Case diagramu...
Wednesday, April 19, 2006 3:34:58 PM (Central Europe Standard Time, UTC+01:00)
Teď bych to viděl na jasný vztah extend (UC002 rozšiřuje UC001). Akorát ty názvy těch UC jsou IMHO nešťastné (přinejmenším mne matou). Shodneme se alespoň na scénařích?

UC001:
precondition: zákazník si vybral nejaké zboží
stručný scénář:
* zákazník zadá typ platby a informace potřebné k provedení platby
* extension point: pokud se má platit kartou, proveď UC002
* pokud UC002 skončil neúspěšně, jdi na první bod scénaře
* založ objednávku v systému

UC002:
* validuj kartu
* proveď platbu
Wednesday, April 19, 2006 3:44:05 PM (Central Europe Standard Time, UTC+01:00)
Ano shodneme, UC 001 je jen fragment celeho UC, ale to neni podstatne.
Presto bych zpoochybnil, ze to je jasny vztah Extend - ted jste prave narazil na misto, kvuli kteremu jsem tuhle "hadanku" daval na web :)
Wednesday, April 19, 2006 4:14:14 PM (Central Europe Standard Time, UTC+01:00)
Hmm... IMHO jediné zde diskutabilní je to, že další provádění UC001 (za ext. pointem) závisí na výsledku UC002. To je podle specifikace UML typické pro include. Ale korektní řešení mi přijde poněkud umělé a méně přehledné: UC001 by musel includovat nějaký obecný UC "validuj platbu" (vracející implicitně "true"), jehož specializací by bylo něco podobného UC002 ("validuj platbu kartou"). Ale UC002 by se možná muselo rozdělit na 2 UC - tady bych se musel znovu ptát zákazníka, zda validace platby kartou má/může obsahovat i vlastní platbu nebo ne.

Ale abych byl upřímný, dal bych asi přednost svému předchozímu řešení, i když možná není zcela korektní dle specifikace UML.
Wednesday, April 19, 2006 10:09:17 PM (Central Europe Standard Time, UTC+01:00)
Extend to neni, protoze extend je "funkcionalita navic". Je to proste include a gen-spec :)
Thursday, April 20, 2006 8:31:52 AM (Central Europe Standard Time, UTC+01:00)
Podle zadání se přece při jiných typech plateb než kartou UC002 ani jiná validace vůbec neprovádí a objednávka se zakládá rovnou. Při určitých podmínkách (platba kartou) je to funcionalita navíc, která rozšiřuje UC001.
Thursday, April 20, 2006 6:27:04 PM (Central Europe Standard Time, UTC+01:00)
Cituji ze zadání: ... Jedním z možných typů platby je platba kartou. ... = gen-spec

Příklad na extend: Platba je možná pouze kartou. Uživatel má v průběhu platby možnost zkontrolovat stav účtu na kartě.
Friday, April 21, 2006 10:13:28 AM (Central Europe Standard Time, UTC+01:00)
to Martin: Neřešíte zadání. Tam není nic o řešení vztahu mezi UC "provést platbu" a UC "provést platbu kartou", ale mezi UC001 a UC002. Možná jsem špatně pochopil otázku, ale ta zní "Jaký je vztah mezi těmito případy užití (tj. mezi UC001 a UC002)?"

Navíc u vámi uvedených případů užití platba a platba kartou to může a nemusí být vztah gen-spec. UC nejsou třídy (kde by to byl nejspíš jasný gen-spec). Pokud by např. scénář UC označeného "platba" obsahoval úplně stejné kroky pro všechny typy plateb a jen pro platbu kartou by bylo nutné provést něco "navíc" - např. validaci karty a částky na účtu, tak je to zase spíše odpovídá vztahu "extend".
Friday, April 21, 2006 10:19:08 AM (Central Europe Standard Time, UTC+01:00)
UC vychazeji ze zadani, takze je dobre, kdyz nekdo uvayuje i v kontextu zadani. Zamerne jsem neposkytl vice iformaci, abych slysel vice nazoru...
Friday, April 21, 2006 11:47:13 AM (Central Europe Standard Time, UTC+01:00)
Protest, otázka na zákazníka a popel.

1. Protestuji proti zatajování informací :-). Zákazník si většinou neuvědomuje, že mi zatajil zcela zásadní věci, ale vy, René, mi to děláte schválně :-). To je unfair. Musí být dán rozumný kontext, co se má řešit. V rozsahu komentářů blogu nelze IMHO řešit, jaký vliv na založení objednávky má to, zda je zákazník plátce DPH, zda je z EU nebo cizák, nebo že při faktuře zaslané poštovním holubem bude jiná splatnost než u faktury zaslané e-mailem. Ale teď vážně, otázka na zákazníka:

2. Pořád si nějak nemůžu dát dohromady "větší" obraz toho systému. V zadání sice je, že platba kartou je jen jeden způsob z mnoha, ale je mi nějaké podezřelé, že zrovna jenom ta karta se míchá zrovna do založení objednávky. Rozumím tomu správně, že pokud se platí kartou, tak se platba provede (tj. dokoná) *před* založením objednávky a pokud ta platba je jiným způsobem, tak se platba provede až *po* založení objednávky (tj. mimo rozsah UC001)? Proč to tak vlastně je? Nešlo by zákazníka nějak přesvědčit (tj. v českých poměrech mírně zkorumpovat :-), aby se to nějak sjednotilo? Já bych pak o tom nemusel tolik přemýšlet a třikrát po sobě číst kapitolu UC v UML specifikaci. Protože jsem už to ale přečetl (a něco málo z toho i pochopil - dá-li se to u mne tak eufemisticky nazvat), tak

3. si sypu popel na hlavu, extend by to být fakt neměl, protože dle specifikace ten rozšiřující UC nesmí (přímo) ovlivnit běh rozšířeného UC, což zde neplatí. Martinův příklad na extend je přesně to, co má extend být.
Friday, April 21, 2006 2:46:04 PM (Central Europe Standard Time, UTC+01:00)
no, takže už to mé řešení vysvětlovat nemusím, že ? padly tady argumenty, proč to nemůže být include, a proč to nemůže být extend : jediný další možný vztah mezi use-cases je generalization :-)
jenže generalization v tomto případě (kdy parent je celé U001) mi připadne příliš "široké", proto jsem navrhl "vytrhnout" z UC001 menší UC003 a až z něj vytvářet child use case(s).
stačí zdůvodnění ?
Friday, April 21, 2006 3:49:58 PM (Central Europe Standard Time, UTC+01:00)
IMHO vztah gen-spec případů užití "platba" a "platba konkrétní metodou" ale přináší problém, pokud je správný můj předpoklad, že se UC "platba kartou" volá z jiného UC než UC pro platbu jinou metodou.
Monday, April 24, 2006 12:00:27 AM (Central Europe Standard Time, UTC+01:00)
to pavel s : to jsem nějak nepochopil : máme "UC001 založení objednávky", "UC002 platba kartou" a navrhuju založit nové "UC003 platba" : gen-spec je mezi "UC003 platba" a "UC002 platba kartou" : můžou být založeny další UC00x pro další speciální způsoby platby; jaký je problém ?
Monday, April 24, 2006 6:30:09 AM (Central Europe Standard Time, UTC+01:00)
Už jsem jeden příspěvek do této diskuse napsal, ale neobjevil se tu, takže to zkusím znovu.
V jednom z možných řešení celého problému podle zadání je obsaženo i řešení hádanky p. Steina. Pozměním zavedené číslování UC, aby lépe odpovídalo navrhovanému řešení:
UC001 - Založení objednávky zákazníkem je UC zastřešující celou akci a končí vznikem objednávky, nebo stornováním celé akce. UC001 includes UC0011 - Výběr zboží ("Zákazník v našem obchodě vybírá zboží ..."), UC0012 - Prohlížení košíku, UC0013 - Potvrzení objednávky.
UC0013 includes UC00130 - Výběr typu platby ("... a poté si může vybrat, jak jej uhradí"). UC00130 je abstraktní, zahrnující prvky společné pro všechny možné typy plateb ("Jedním z možných typů platby je platba kartou."). Společným prvkem mj. je, že pokud tento UC z nějakého důvodu neskončí úspěchem, skončí neúspěšně i nadřazený UC0013. Bez úspěšného provedení UC0013, tedy bez potvrzení objednávky, neskončí úspěšně ani celý UC001. Dalším typem platby může být platba na fakturu, při které se ověřují neuhrazené pohledávky apod., jiné typy plateb nemusí mít žádné ověřování a skončí vždy úspěšně. UC0013 může obsahovat další UC, jako třeba Výběr způsobu dopravy atd.
UC00131 - Platba kartou inherits UC00130, includes UC001311 - Ověření karty. Pokud tento UC neskončí úspěšně, neskončí úspěšně ani nadřazený UC00131.
Tedy vztah mezi UC001 Založení objednávky zákazníkem a UC00131 Platba kartou není přímý ale přes 2 vložené UC s 2 vazbami includes a 1 inherits (gen spec).
Monday, April 24, 2006 2:04:35 PM (Central Europe Standard Time, UTC+01:00)
to pavus: Vaše řešení je IMHO logické, pokud v určitém kroku scénáře UC001 dojde k platbě (include vašeho UC003). UC003 zajistí provedení obecných kroků pro platbu a nějaký potomek UC003 - např. UC002 - pak zajistí provedení těch správných kroků pro konkrétní druh platby.

Jenže zadání IMHO neříká, že se platba kterýmkoliv způsobem provádí v tom daném kroku před založením objednávky. To platí jen pro platbu kartou a ne třeba pro platbu za hotové (na dobírku). UC "platba za hotové" by se prováděl v úplně jiném kroku a pravděpodobně i v konextu jiného UC (např. doručení).

Má pak smysl dělat generalizaci typu "obecná platba"?
Monday, April 24, 2006 4:17:26 PM (Central Europe Standard Time, UTC+01:00)
to pavel s: ad "Jenže zadání IMHO neříká, že se platba kterýmkoliv způsobem provádí v tom daném kroku před založením objednávky."
no já to v zadání vidím, určení kroku pro výběr způsobu platby : píše se tam doslova "Zákazník v našem obchodě vybírá zboží a poté si může vybrat, jak jej uhradí."
takže bez ohledu na konkrétní způsob platby se výběr způsobu platby provádí vždy ve stejném místě - po výběru zboží (?);
sice není přesně uvedeno, kdy se zakládá samotná objednávka, IMHO ale bych asi předpokládal (kdybych nad tím tedy uvažoval :-), že k založení objednávky musí dojít až poté, co zákazník vybere způsob platby (jaký smysl by měla založená objednávka bez zadaného způsobu platby ? tudíž založíme objednávku až po výběru platby, a to pro jakýkoliv způsob platby) --> vždy ve stejném kroku dojde k výběru zboží, vždy ve stejném kroku k volbě způsobu platby, a vždy ve stejném kroku k založení objednávky - nebo ne?
Tuesday, April 25, 2006 10:34:58 AM (Central Europe Standard Time, UTC+01:00)
to pavus: Souhlasím s tím, že vždy ve stejném kroku (nejspíše v UC001) dojde k výběru způsobu platby. Ale to neplatí o vlastním uskutečnění platby. Já zadání chápu tak (a proto si myslím že je to hádanka), že u platby kartou to probíhá takto (řekněmě, že zboží má zákazník už vybrané):
1. zákazník si vybere platbu kartou,
2. zákazník zadá adresu a číslo karty,
3. provede se UC002 - tj. autorizace a ta vlastní platba kartou (tj. zákazníkovi se strhnou ty peníze),
4. pokud platba dopadla dobře, tak se teprve nyní založí v systému ta objednávka, podle které se bude expedovat zboží.

Pokud ale to chce zákazník na dobírku, tak:
1. zákazník si vybere platbu za hotové na dobírku
2. zákazník zadá adresu
3. v systému se založí objednávka

Ve druhém případě vlastní platba zákazníkem probíhá až při vlastním fyzickém převzetí zboží - to může být o týden později a nejspíše v rámci UC "dodávka zboží".

BTW, při té platbě za hotové vzniká podobný vztah UC "dodávka zboží" někdy volá UC "platba za hotové a někdy ne".

Kdybychom si to rozšířili o možnost platby fakturou a možnost platby předem převodem z účtu - tak máme 4 UC pro 4 různé způsoby plateb, ale každý z nich se volá v jiném kroku (často jiného) případu užití. V takovém případě mi nepřijde moc užitečné dělat nějakého obecnějšího předka pro platbu. Případná společná funcionalita se tam dá logičtěji strčit přes include nebo extend.
Wednesday, May 03, 2006 4:57:32 PM (Central Europe Standard Time, UTC+01:00)
no, myslím, že ještě nežijeme v době, kdy by platby kartou trvaly "desetiny vteřiny";
takže bychom UC pro platbu kartou mohli chápat jako UC pro "zadání údajů o platbě kartou": tj. ať platba nastane kartou nebo fakturou nebo převodem z účtu, tak vždy plátce jen vybere způsob platby a zadá nutné údaje a samotný převod peněz pak nastane mnohem později (za několik dní či hodin či vteřin) ...
Pokud je můj předpoklad správný, tak mi pořád připadá nejvhodnější řešení tak, jak jsem navrhnul již v prvním komentáři, a pořadí akcí je :
- výběr zboží
- výběr způsobu platby
- zadání podrobností o platbě
- potvrzení údajů
- založení objednávky
- fyzický převod peněz - provedení platby (až někdy později jiným usecase)

a co autor - po dvou týdnech už by mohl říct řešení hádanky (?) - spíš si ale myslím, že jednoznačně správné řešení neexistuje ....
Comments are closed.