Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Chain of Responsibility. Chain of responsibility - účel Účel  Umožňuje zrušení vazby mezi odesílatelem a příjemcem požadavku  Umožňuje zaslání požadavku.

Podobné prezentace


Prezentace na téma: "Chain of Responsibility. Chain of responsibility - účel Účel  Umožňuje zrušení vazby mezi odesílatelem a příjemcem požadavku  Umožňuje zaslání požadavku."— Transkript prezentace:

1 Chain of Responsibility

2 Chain of responsibility - účel Účel  Umožňuje zrušení vazby mezi odesílatelem a příjemcem požadavku  Umožňuje zaslání požadavku (zprávy) neznámým příjemcům  Nemusí být předem zřejmé, který objekt požadavek obslouží  Snadná rozšiřitelnost, či změna za běhu  Příjemci tvoří spojový seznam předávají si požadavky (dokud je někdo nezpracuje)

3 Chain of responsibility – struktura Struktura Účastníci Handler  definuje rozhraní pro zpracování požadavků  volitelně implementuje ukazatel na následníka ConcreteHandler  zachytává požadavek, který umí zpracovat  může přistupovat na svého následníka Client  vyvolává požadavek předáním na objekt ConcreteHandler zapojený do řetězu

4 Chain of responsibility - příklady Subsystém pro počítání hodnoty mincí  Nápojový automat přijímá mince o nominálních hodnotách 1, 2, 5, 10, 20 a 50Kč.  Má pouze jeden vstup na mince… a několik zásobníků na mince (podle nominální hodnoty). Kontextová nápověda widgetu (viz GoF)  Obsah nápovědy dle závislosti na kontextu, ve kterém se widget nachází. Vzdálené zpracování požadavků  Skupina serverů poskytuje nějakou (stejnou) službu.  Klientům záleží pouze na poskytnutí služby, ne na tom, kým je nakonec poskytnuta.

5 Chain of responsibility – implementace Subsystém pro počítání hodnoty mincí  Nominální hodnota mince je určena rozměry a hmotností  Bázový handler class Coin { public float Weight { get; set; } public float Diameter { get; set; } } abstract class CoinHandlerBase { protected CoinHandlerBase _successor; public abstract void HandleCoin(Coin coin); public void SetSuccessor(CoinHandlerBase successor) { _successor = successor; } Lze samozřejmě předávat například v konstruktoru

6 Chain of responsibility – implementace  Handlery pro konkrétní mince class OneCrownHandler : CoinHandlerBase { public override void HandleCoin(Coin coin) { if (Math.Abs(coin.Weight – 3,25) < 0,02) && Math.Abs(coin.Diameter – 18) < 0,1) { // Zpracování mince } else { _successor.HandleCoin(coin); } Je tento handler určen ke zpracování dodané mince? class TwoCrownsHandler : CoinHandlerBase { … } class FiveCrownsHandler : CoinHandlerBase { … } class TenCrownsHandler : CoinHandlerBase { … } class TwentyCrownsHandler : CoinHandlerBase { … } class FiftyCrownsHandler : CoinHandlerBase { … } Rozdíl pouze v klauzuli if funkce HandleCoin(), jinak totožné s příkladem OneCrown

7 Chain of responsibility – implementace Použití CoinHandlerBase c1 = new OneCrownHandler(); CoinHandlerBase c2 = new TwoCrownsHandler(); CoinHandlerBase c5 = new FiveCrownsHandler(); CoinHandlerBase c10 = new TenCrownsHandler(); CoinHandlerBase c20 = new TwentyCrownsHandler(); CoinHandlerBase c50 = new FiftyCrownsHandler(); c1.SetSuccessor(c2); c2.SetSuccessor(c5); c5.SetSuccessor(c10); c10.SetSuccessor(c20); c20.SetSuccessor(c50); Coin one = new Coin( Diameter = 24,47F, Weight = 6,5F ); Coin ten = new Coin( Diameter = 27,24F, Weight = 8,1F ); Coin unknown = new Coin( Diameter = 42,89F, Weight = 1,0F ); CoinHandlerBase handler = c1; handler.HandleCoin(one); handler.HandleCoin(ten); handler.HandleCoin(unknown); Vytvoření handlerů pro validní mince ?!? Mince k použití Vstupní bod do subsystému Nastavení pořadí zpracování

8 Chain of responsibility – unknown Řešení class UnknownHandler : CoinHandlerBase { public override void HandleCoin(Coin coin) { // Zpracování neznáme mince } Vytvoření handleru pro neznámé mince... CoinHandlerBase c50 = new FiftyCrownsHandler(); CoinHandlerBase unknownHandler = new UnknownHandler();... c50.SetSuccessor(unknownHandler);... Coin unknown = new Coin( Diameter = 42,89F, Weight = 1,0F );... handler.HandleCoin(unknown); Neznámé mince zpracuje UnknownHandler

9 Chain of responsibility – vzdálené zpracování Vzdálené zpracování požadavků  Skupina serverů poskytuje nějakou (stejnou) službu.  Klientům záleží pouze na poskytnutí služby, ne na tom, kým je nakonec poskytnuta. Vzdálené zpracování požadavků – bez použití NV  Definice serveru a jeho služeb – původní řešení class Server { private static int mNextID = 1; private int mID = mNextID++; private bool IsBusy() {…} public bool handle(int num) { if (IsBusy()) { return false; } System.out.println( mID + " handled " + num ); return true; }

10 Chain of responsibility – vzdálené zpracování Vzdálené zpracování požadavků – s použitím NV  Definice serveru a jeho služeb – nové řešení class Server { private static int mNextID = 1; private int mID = mNextID++; private Server mNextServer; private bool IsBusy() {…} public void add(Server next) { if (mNextServer == null) mNextServer = next; else mNextServer.add(next); } public void wrapAround(Server root) { if (mNextServer == null) mNextServer = root; else mNextServer.wrapAround(root); } public void handle(int num) { if (IsBusy()) mNextServer.handle(num); else System.out.println( mID + " handled " + num ); } Server nemůže zpracovat požadavek, předává ho dále Funkce slouží k uzavření serverů „do kruhu“, každý požadavek musí být zpracován Propojí poslední server s prvním

11 Chain of responsibility – rozdíl v použití Bez použití NV public class ChainDemo { public static void main(String[] args) { Server[] nodes = {new Server(), new Server(), new Server()}; int request = 1; j = 0; while (!nodes[j].handle(request)) j = (j + 1) % nodes.length; } S použitím NV public class ChainDemo { public static void main(String[] args) { Server serverRoot = new Server(); serverRoot.add( new Server() ); serverRoot.wrapAround( serverRoot ); int request = 1; serverRoot.handle(request); }

12 Chain of responsibility - následník Class Handler { public: HelpHandler(HelpHandler* s) : _successor(s) { } virtual void Handle (); private: Handler* _successor; }; void Handler::Handle() { if (_successor) { _successor->HandleHelp(); } class ConcreteHandler : public Handler { public: ConcreteHandler(Handler* h); virtual void Handle(); bool HasHandle(); }; ConcreteHandler:: ConcreteHandler(Handler* h) : Handler(h) { } void ConcreteHandler::HandleHelp () { if (HasHandle()) { // handle } else { HelpHandler::HandleHelp(); } Co když zapomenu zavolat nejakou funkci, která předává požadavek dál?

13 Chain of responsibility - následník public abstract class ClassicChain { private ClassicChain next; public ClassicChain(ClassicChain nextNode) { next = nextNode; } public final void start(ARequest request) { boolean handledByThisNode = this.handle(request); if (next != null && !handledByThisNode) next.start(request); } protected abstract boolean handle(ARequest request); } public class AClassicChain extends ClassicChain { protected boolean handle(ARequest request) { boolean handledByThisNode = false; if(someCondition) { //Do handling handledByThisNode = true; } return handledByThisNode; } Volání nasledníka vynutíme pomocí programovacího jazyka, nikoliv pomocí paměti programátora

14 Chain of responsibility – s podtřídami Zpracování požadavků s podtřídami:  Podtřída zpracuje pouze požadavky, o níž má zájem, další požadavky jsou předávány do rodičovské tříd y Třeba definovat typ požadavku class ExtendedHandler : public Handler { public: virtual void HandleRequest(Request* theRequest); //... }; void ExtendedHandler::HandleRequest (Request* theRequest) { switch (theRequest->GetKind()) { case Preview: // handle the Preview request break; default: // let Handler handle other requests Handler::HandleRequest(theRequest); }

15 Chain of responsibility – použitelnost Použitelnost  Chceme zaslat zprávu a nevíme kdo ji zpracuje nebo nás to nezajímá Důležitý je výsledek!  Pokud více než jeden příjemce může přijmout zprávu a není apriori známo který Výhody  Odděluje odesílatele od příjemců  Zjednodušuje odesílatele – neobsahuje reference na všechny možné příjemce – viz „vzdálené zpracování požadavků“  Možnost měnit řetěz dynamicky, za běhu programu Nevýhody  není zaručeno, že nějaký příjemce zprávu přijme – viz „subsystém pro počítání hodnoty mincí bez UnknownHandler“ při implementaci na to tedy musíme myslet

16 Chain of responsibility – známé použití Známé použití  Grafické toolkity (Java AWT – nevhodné použití, neujalo se)  Okenní systémy běžně používáno pro zpracování událostí jako kliknutí myši, stisk klávesy  Windows hooks Požadavek projde všechny handlery  Java Servlet Filter Http request může zpracovat více filtrů  Distribuované systémy v řetězu (do kruhu) je zapojena množina serverů nabízejících určité služby klient předá požadavek libovolnému serveru servery si mezi sebou posílají požadavek, dokud jej některý nezpracuje

17 Chain of Resposibility – souvisejíci NV Související NV  Composite Je-li řetěz objektů využívaný součástí rozsáhlejší struktury, je tato struktura obvykle tvořena pomocí Composite vzoru

18 Chain of Resposibility – zdroje GoF Různé detaily implementace  Nepoužité příklady   Responsibility.htm   Použití ve Windows hooks 


Stáhnout ppt "Chain of Responsibility. Chain of responsibility - účel Účel  Umožňuje zrušení vazby mezi odesílatelem a příjemcem požadavku  Umožňuje zaslání požadavku."

Podobné prezentace


Reklamy Google