Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

vzor Command

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: vzor Command

Autor: Programmer.CZ

14:40:47 20.05.2008

1.

píšeš o nějaký knize, ale já nejsem jasnovidec... takže netuším o jaký knize píšeš. Ten diagram asi není úplně do puntíku detailní UML diagram s kvalifikátorama (public, private, protected...), prostě jen sděluje základní myšlenku toho vzoru a ta je velice jednoduchá.
Receiver představuje nějaký objekt, který potřebuješ pro provedení té akce. Třeba když potřebuješ uložit soubor, tak Receiver bude objekt představující ten soubor, na kterým zavoláš metodu save(). Podle mě je zbytečný dělat nějakou třídu/rozhraní Reciver. Když budu mít obecný Command s "Object reveiver" proměnnou, příp. Object[] receivers, tak když píšu potomka tohoto commandu pro specifickou akci, tak samozřejmě vím, s čím potřebuju pracovat a co má být v execute(), na co receivera přetypovat, jaký metody na něm můžu volat apod.


2. jediný způsob jak zaregistrovat command u invokeru je samozřejmě zavolat nějakou add metodu. To ale neznamená, že to musí být asociace mezi clientem a invokerem. To může jít klidně přes 10 dalších objektů, client vytvoří commandy, uloží je někam, reference se můžou propagovat mezi dalšími objekty dané aplikace atd. A ten obrázek UKAZUJE pouze základní strukturu vzoru.


3. Základní motivace pro vzor je mít tvárný a snadno rozšiřitelný model aplikace. tak když si to upravíš, tak to asi už nebude stejný => hybrid. Hlavně mám dojem, že pořád nechápeš rozdíl command vs. receiver. Mám dojem, že spíš tvoje úprava spočívá v tom, že client by moh implementovat třeba ICommand, má tedy execute() a nepotřebuje receivera. Pak je možný objekt Client zaregistrovat normálně u Invokera, protože je to Command.


4. a 5. viz. předchozí body. Na těch stránkách VŠE jsou celkem učebnicový příklady proč command používat. Pokud ti to stále není jasný, tak já už nevím, je to jeden z nejprimitivnějších vzorů po singletonu a tovární metodě :)

Citovat příspěvek

 

Re: vzor Command

Autor: himalaya

10:46:01 20.05.2008

1. Command obsahuje proměnnou receiver - odkaz na objekt Receiver, přes který volá jeho metody. V UML je to role a role se dávájí na druhou stranu. Receiver vystupuje pro ConcreteCommand v roli receiver, takže by receiver měl být asi u třídy Receiver a ještě by u něj mělo být znaménko mínus nebo #, protože by to neměla být veřejná proměnná. Tak jsem to aspoň zatím pochopil. V knize je ale "receiver" u třídy Concretecommand a není u něj žádné znaménko. Na webu je receiver u třídy Receiver a je u něj +, takže jsem z toho mírně zmaten.

2. Asi na tom něco bude. Nepodstatné věci se nejspíše vynechávají. Stejně mi tam ta šipka chybí, protože jediný způsob jak zaregistrovat command u invokeru je podle mě zavolání metody třídy Invoker, řekněme Add(Command c), to proto, že je zde naznačeno, že se Invoker skladá (agregace) z objektů Command a Client vytváří ConcreteCommand.

3-4. Protože metody , které vykonávají příkazy můžou být přímo v hlavní třídě aplikace. A tato třída je Client. Zajímá ě, když si upravím vzor podle sebe, jestli to bude pořád ten vzor a nebo nějaký hybrid :) Kde je mez, kterou když překročím, už nemůžu říct, že je to podle návrhového vzoru.

Myslím, že by proměnná receiver měla být typu Receiver a ne Object. V metodě execute se totiž musí volat metody třídy Receiver, které plní konkrétní příkazy. Když bude proměnná receiver typu Object, tak je nebude možné volat.

5. :-) moc není. Jde asi o to, že příjemce se může měnit, takže stejný příkaz se může provést různým způsobem v závislosti na příjemci. Když to ale nepotřebuju (mám jen jednoho příjemce), tak můžu vložit kód přímo do metody execute v třídě ConcreteCommand.


Zatím se mi to zdá jako zbytečná režie vytvářet plno tříd pro různé příkazy. Možná jsem ale nepochopil pravý účel tohoto návrhového vzoru.

Citovat příspěvek

 

Re: vzor Command

Autor: Programmer.CZ

12:50:31 18.05.2008

1. příjemce dané akce by měl být na straně ConcreteCommand, protože právě příjemce dodává potřebný údaje o tom co se udělá v metodě execute(). Čili šipka od ConcreteCommand k Receiver.

2. Způsob jakým bude ten command zaregistrován u Invokeru není až tak podstatný a může být různý, proto to asi není v diagramu zahrnuto, diagramy mají zdůrazňovat pouze podstatné věci, aby byly přehledné.

3. Návrhové vzory se jistě dají ještě ohýbat, ale nemělo by to asi zasáhnout/ovlivnit původní motivaci. Záleží na příkladě, proč bys to dělal?

4. Návrhový vzory nejsou nějaké dogma, může se vyskytnout případ, kdy bude zbytečné vytvářet Příjemce jako zvláštní třídu, nicméně v drtivé většině případů bych řekl, že tam nějaký bude. Hlavně si musíš uvědomit, že to neznamená, že Příjemce je nějaká další zbytečná třída. Příjemce je v drtivé většině případů třída, která má v celé aplikaci svoje jasný místo a už existuje: dokument, GUI komponenta - třeba tabulka apod. Aby sis nemyslel, že to je nějaká buzerace vytvářet umělý třídy jen proto, abys splnil požadavky návrhovýho vzoru.

př. v javě: Command bude mít instanční proměnnou:

Object reveiver; //strč si tam cokoliv


5. To je snad jasný z předchozích bodů :)

Citovat příspěvek

 

vzor Command

Autor: himalaya

9:27:10 18.05.2008

Bádám nad vzorem Command a mám spíše více otazek než odpovědí.

1. V knize je schéma vzoru Command stejné jako http://objekty.vse.cz/img/nvzory36.gif, ale role "+receiver" se jmenuje "příjemce" a je na druhé straně (u třídy ConcreteCommand). Tak nevím co je správně.

2. Proč není asociace mezi třídami Client a Invoker? Když Client vytváří Command, tak mu musí určit příjemce a uložit Command do Invokeru. Musí tak zavolat metodu Invokeru.

3. Když bude Receiver a Client spojený do jedné třídy, bude to pořád vzor Command?

4. Nerozumím moc použití. To se opravdu pro každý příkaz musí vytvořit objekt, který obsahuje metodu, která zavolá konkrétní metodu Receiveru? Tzn. pro 10 příkazů se musí vytvořit 10 tříd, které budou obsahovat volání 10 různých metod?

5. Proč se specifikuje vůbec nějaký příjemce a není kód přímo v metodě Execute daného konkrétního příkazu?

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: