Řetězec odpovědnosti

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 27. července 2013; kontroly vyžadují 27 úprav .
Řetězec odpovědnosti
Řetězec odpovědnosti
Typ behaviorální
Účel pro organizaci v systému úrovní odpovědnosti
Související šablony Linker
Popsáno v Návrhové vzory Ano

Řetězec odpovědnosti je vzorec  chování navržený tak , aby organizoval úrovně odpovědnosti v systému.

Aplikace

Šablona se doporučuje používat v následujících podmínkách:

Příklady

Příklad Delphi

Zdrojový kód v Delphi unitPattern ; _ rozhraní používá SysUtils ; typ TPurchase = class public Číslo : integer ; Částka : Dvojnásobek ; Účel : řetězec _ konstruktor Create ( num : integer ; am : Double ; pur : string ) ; konec ; IApprover = interface [ '{3ACA3967-FFCF-48A1-AC45-9A9B98A8DD96}' ] procedure SetSuccessor ( nástupce : IApprover ) ; procedura ProcessRequest ( nákup : TPurchase ) ; konec ; TApprover = chráněná třída ( TInterfacedObject , IApprover ) FSuccessor : IApprover ; veřejný postup SetSuccessor ( nástupce : IApprover ) ; procedura ProcessRequest ( nákup : TPurchase ) ; virtuální ; abstraktní ; konec ; TDirector = class ( TAApprover ) procedure ProcessRequest ( nákup : TPurchase ) ; přepsat ; konec ; TVicePresident = class ( TAApprover ) procedure ProcessRequest ( nákup : TPurchase ) ; přepsat ; konec ; TPresident = class ( TAApprover ) procedure ProcessRequest ( nákup : TPurchase ) ; přepsat ; konec ; implementace { TApprover } postup TApprover . SetSuccessor ( nástupce : IApprover ) ; begin FSuccessor := následník ; konec ; { TDirector} postup TŘeditel . ProcessRequest ( nákup : TPurchase ) ; začít v případě nákupu . Částka < 1000 0,0 pak WriteLn ( Formát ( 'Požadavek schválený ředitelem # %d' , [ nákup . Číslo ])) jinak if FSuccessor <> nula then FSuccessor . ProcessRequest ( nákup ) ; konec ; {TVicePresident} postup TVicePrezident . ProcessRequest ( nákup : TPurchase ) ; začít v případě nákupu . Částka < 2500 0,0 pak WriteLn ( Formát ( 'Požadavek schválený viceprezidentem # %d' , [ nákup . Číslo ])) jinak if FSuccessor <> nula then FSuccessor . ProcessRequest ( nákup ) ; konec ; {TPprezident} postup TPrezident . ProcessRequest ( nákup : TPurchase ) ; začít v případě nákupu . Částka < 10 000 0,0 pak WriteLn ( Formát ( 'Prezident schválil požadavek # %d' , [ nákup . Číslo ])) jinak WriteLn ( Formát ( 'Požadavek č. %d vyžaduje schůzku vedení!' , [ nákup . Číslo ])) konec ; { TPkoupit } konstruktor TPkoupit . Create ( num : integer ; am : Double ; pur : string ) ; beginNumber : = num ; Částka := am ; Účel := pur ; konec ; konec . //_________________________________________________________________________ program Behaviorální . ChainOfResponsibility . vzor ; {$APPTYPE KONZOLE} používá SysUtils , Vzor v 'Pattern.pas' ; varDirector : IApprover ; _ Místopředseda : I Schvalovatel ; Předseda : Schvaluji ; Nákup : TPkoupě ; begin ReportMemoryLeaksOnShutDown := DebugHook <> 0 ; zkuste Director := TDirector . vytvořit ; VicePresident := TVicePresident . vytvořit ; Prezident := TPrezident . vytvořit ; tryDirector . _ SetSuccessor ( viceprezident ) ; místopředseda . SetSuccessor ( prezident ) ; Nákup := TPkoupit . Vytvořit ( 2034 , 35 0,00 , 'Zásoby' ) ; ředitel . ProcessRequest ( Nákup ) ; Nákup . zdarma ; Nákup := TPkoupit . Vytvořit ( 2035 , 3259 0.10 , 'Projekt X' ) ; ředitel . ProcessRequest ( Nákup ) ; Nákup . zdarma ; Nákup := TPkoupit . Vytvořit ( 2036 , 12210 0,00 , 'Projekt Y' ) ; ředitel . ProcessRequest ( Nákup ) ; Readln ; Konečně nákup . zdarma ; konec ; kromě na E : Exception do Writeln ( E. Classname , ' : ' , E. Message ) ; konec ; konec .

Příklad PHP 5

Zdrojový kód v PHP 5.3 jmenný prostor ChainOfResponsibility { abstraktní třída Logger { constERR = 3 ; _ const UPOZORNĚNÍ = 5 ; const DEBUG = 7 ; chráněná $maska ​​; // Další prvek v řetězci odpovědností chráněn $next ; public function __construct ( $mask ) { $this -> mask = $mask ; } public function setNext ( Logger $log ) { $this -> next = $log ; return $log ; } public function message ( $msg , $priority ) { if ( $priority <= $this -> mask ) { $this -> writeMessage ( $msg ); } if ( $this -> další != null ) { $this -> další -> zpráva ( $msg , $priority ); } } chráněná abstraktní funkce writeMessage ( $msg ); } class StdoutLogger rozšiřuje Logger { chráněná funkce writeMessage ( $msg ) { echo sprintf ( "Zápis do stdout:%s \n " , $msg ); } } class EmailLogger rozšiřuje Logger { chráněná funkce writeMessage ( $msg ) { echo sprintf ( "Odeslání přes email:%s \n " , $msg ); } } class StderrLogger rozšiřuje Logger { chráněná funkce writeMessage ( $msg ) { echo sprintf ( "Odesílání do stderr:%s \n " , $msg ); } } //řetězec odpovědnosti class ChainOfResponsibilityExample { public function run () { // sestavení řetězce odpovědnosti $logger = new StdoutLogger ( Logger :: DEBUG ); $logger1 = $logger -> setNext ( new EmailLogger ( Logger :: UPOZORNĚNÍ )); $logger2 = $logger1 -> setNext ( new StderrLogger ( Logger :: ERR )); // Obsluhováno StdoutLoggerem $logger -> message ( "Zadávání funkce y." , Logger :: DEBUG ); // Obsluhováno StdoutLoggerem a EmailLoggerem $logger -> message ( "Krok1 dokončen." , Logger :: UPOZORNĚNÍ ); // Obsluhováno všemi třemi loggery $logger -> message ( "Došlo k chybě." , Logger :: ERR ); } } $chain = new ChainOfResponsibilityExample (); $chain -> spustit (); }

Příklad Java

Zdroj Java balíček chainofresp ; abstract class Logger { public static int ERR = 3 ; public static int UPOZORNĚNÍ = 5 ; public static int DEBUG = 7 ; chráněná vnitřní maska ​​; ​​_ // Další prvek v řetězci odpovědnosti chráněn Logger next ; public Logger setNext ( Logger log ) { next = log ; vrátit deník ; } public void message ( String msg , int priority ) { if ( priorita <= maska ) { writeMessage ( msg ); } if ( next != null ) { next . zpráva ( msg , priorita ); } } abstrakt chráněný void writeMessage ( String msg ); } class StdoutLogger rozšiřuje Logger { public StdoutLogger ( int mask ) { this . maska ​​= maska ​​; } protected void writeMessage ( String msg ) { Systém . ven . println ( "Zápis do stdout: " + msg ); } } class EmailLogger rozšiřuje Logger { public EmailLogger ( int mask ) { this . maska ​​= maska ​​; } protected void writeMessage ( String msg ) { Systém . ven . println ( "Odeslání e-mailem: " + zpráva ); } } class StderrLogger extends Logger { public StderrLogger ( int mask ) { this . maska ​​= maska ​​; } protected void writeMessage ( String msg ) { Systém . ven . println ( "Odesílání do stderr: " + msg ); } } public class ChainOfResponsibilityExample { public static void main ( String [] args ) { // Sestavení řetězce odpovědnosti Logger logger , logger1 , logger2 ; logger = new StdoutLogger ( Logger . DEBUG ); logger1 = logger . setNext ( nový EmailLogger ( Logger . UPOZORNĚNÍ )); logger2 = logger1 . setNext ( nový StderrLogger ( Logger . ERR )); // Obsluhováno protokolem StdoutLogger . zpráva ( "Zadávání funkce y." , Logger . DEBUG ); // Zpracovává StdoutLogger a EmailLogger logger . zpráva ( "Krok 1 dokončen." , Logger . UPOZORNĚNÍ ); // Obsluhováno všemi třemi loggery logger . zpráva ( "Došlo k chybě." , Logger . ERR ); } } /* Výstup je: Zápis do stdout: Zadání funkce y. Zápis do stdout: Krok 1 dokončen. Odeslání e-mailem: Krok 1 dokončen. Zápis do stdout: Došlo k chybě. Odesílání e-mailem: Došlo k chybě. Odesílání do stderr: Došlo k chybě. */

Příklad v C#

Zdrojový text v C# // Vzor řetězce odpovědnosti -- Strukturální příklad pomocí System ; jmenný prostor DoFactory.GangOfFour.Chain.Structural { /// <summary> /// Spouštěcí třída MainApp pro Structural /// Vzor návrhu řetězce odpovědnosti. /// </summary> class MainApp { /// <summary> /// Vstupní bod do konzolové aplikace. /// </summary> static void Main () { // Setup Chain of Responsibility Handler h1 = new ConcreteHandler1 (); Handler h2 = new ConcreteHandler2 (); Handler h3 = new ConcreteHandler3 (); h1 . SetSuccessor ( h2 ); h2 . SetSuccessor ( h3 ); // Generování a zpracování požadavku int [] requesty = { 2 , 5 , 14 , 22 , 18 , 3 , 27 , 20 }; foreach ( int request in requests ) { h1 . HandleRequest ( žádost ); } // Počkejte na uživatelskou konzoli . ReadKey (); } } /// <summary> /// Abstraktní třída 'Handler' /// </summary> abstract class Handler { protected Handler následník ; public void SetSuccessor ( nástupce obslužného programu ) { this . následník = nástupce ; } veřejný abstrakt void HandleRequest ( int request ); } /// <summary> /// Třída 'ConcreteHandler1' /// </summary> class ConcreteHandler1 : Handler { public override void HandleRequest ( int request ) { if ( request >= 0 && request < 10 ) { Console . WriteLine ( "{0} zpracoval požadavek {1}" , toto . GetType (). Name , request ); } else if ( následník != null ) { následník . HandleRequest ( žádost ); } } } /// <summary> /// Třída 'ConcreteHandler2' /// </summary> class ConcreteHandler2 : Handler { public override void HandleRequest ( int request ) { if ( request >= 10 && request < 20 ) { Console . WriteLine ( "{0} zpracoval požadavek {1}" , toto . GetType (). Name , request ); } else if ( následník != null ) { následník . HandleRequest ( žádost ); } } } /// <summary> /// Třída 'ConcreteHandler3' /// </summary> class ConcreteHandler3 : Handler { public override void HandleRequest ( int request ) { if ( request >= 20 && request < 30 ) { Console . WriteLine ( "{0} zpracoval požadavek {1}" , toto . GetType (). Name , request ); } else if ( následník != null ) { následník . HandleRequest ( žádost ); } } } } Výstup zpracovaná žádost ConcreteHandler1 2 zpracovaná žádost ConcreteHandler1 5 zpracovaná žádost ConcreteHandler2 14 zpracovaná žádost ConcreteHandler3 22 zpracovaná žádost ConcreteHandler2 18 zpracovaná žádost ConcreteHandler1 3 zpracovaná žádost ConcreteHandler3 27 zpracovaná žádost ConcreteHandler203 _

Příklad C++

Zdrojový text v C++ #include <iostream> /** * Pomocná třída popisující nějaký zločin */ class CriminalAction { kamarád třída policista ; // Policie má přístup k materiálům vyšetřování int složitost ; // Složitost případu const char * popis ; // Stručný popis trestného činu veřejnost : CriminalAction ( int complexity , const char * description ) : komplexita ( complexity ), description ( description ) {} }; /** * Abstraktní policista, který může vyšetřovat zločiny */ třída policista { chráněno : int snížení ; // dedukce (schopnost rozplétat složité případy) pro tohoto policistu Policista * další ; // zručnějšího policajta, který dostane případ, pokud je pro toho současného příliš těžký virtual void researchConcrete ( const char * description ) {} // aktuální vyšetřování veřejnost : Policista ( int deduction ) : deduction ( deduction ), next ( nullptr ) {} virtuální ~ Policista () { smazat další ; } /** * Do řetězce odpovědnosti přidává zkušenějšího policistu, který může převzít * vyšetřování, pokud selže dosavadní */ Policista * setNext ( Policista * policista ) { další = policista ; vrátit další ; } /** * Policista zahájí vyšetřování, nebo pokud je případ příliš komplikovaný, předá jej zkušenějšímu kolegovi */ zrušit vyšetřování ( CriminalAction * CriminalAction ) { if ( dedukce < kriminální akce -> složitost ) { if ( další ) { další -> vyšetřovat ( trestníAkce ); } jinak { std :: cout << "Tento případ nesmí být nikomu prozrazen." << std :: endl ; } } jinak { vyšetřovatKonkrétní ( kriminálníAkce -> popis ); } } }; třída MartinRiggs : veřejný policista { chráněno : void researchConcrete ( const char * description ) { std :: cout << "Vyšetřování případu \" " << popis << " \" pod vedením seržanta Martina Riggse" << std :: endl ; } veřejnost : MartinRiggs ( int dedukce ) : Policista ( dedukce ) {} }; třída JohnMcClane : veřejný policista { chráněno : void researchConcrete ( const char * description ) { std :: cout << "Vyšetřování \" " << popis << " \" Detektiv John McClane" << std :: endl ; } veřejnost : JohnMcClane ( odpočet int ) : Policista ( odpočet ) {} }; třída Vincent Hanna : veřejný policista { chráněno : void researchConcrete ( const char * description ) { std :: cout << "Vyšetřování případu \" " << popis << " \" vedené poručíkem Vincentem Hannou" << std :: endl ; } veřejnost : VincentHanna ( odpočet int ) : Policista ( odpočet ) {} }; int main () { std :: cout << "VYSTUP:" << std :: endl ; Policista * policista = nový MartinRiggs ( 3 ); // policista s nejméně vyšetřovací schopností policista -> setNext ( nový JohnMcClane ( 5 )) -> setNext ( nový Vincent Hanna ( 8 )); // k němu přidejte dva zkušené kolegy policisty -> vyšetřujte ( new CriminalAction ( 2 , "Drogový obchod z Vietnamu" )); policista -> vyšetřovat ( nová CriminalAction ( 7 , "Odvážná bankovní loupež v centru Los Angeles" )); policista -> vyšetřovat ( nová CriminalAction ( 5 , "Série výbuchů v centru New Yorku" )); návrat 0 ; } /** * VÝSTUP: * Vyšetřování vietnamského obchodu s drogami od seržanta Martina Riggse * Vyšetřování Daring Bank Loupež v centru Los Angeles od poručíka Vincenta Hanny * Vyšetřování série bombových útoků v centru New Yorku v podání detektiva Johna McClaina */

Příklad Pythonu

Zdrojový kód v Pythonu manipulátory = [] def car_handler ( func ): handlery . append ( func ) return func třída Auto : def __init__ ( self ): self . jméno = Žádné . km = 11100 vlastní . palivo = 5 vlastní . olej = 5 @car_handler def handle_fuel ( car ): if car . palivo < 10 : tisk ( "přidané palivo" ) auto . palivo = 100 @car_handler def handle_km ( car ): if car . km > 10000 : tisk ( "udělal test auta." ) auto . km = 0 @car_handler def handle_oil ( car ): if car . olej < 10 : tisk ( "Přidaný olej" ) auto . olej = 100 class Garáž : def __init__ ( self , handlery = Žádné ): self . handlers = handlers nebo [] def add_handler ( self , handler ): self . manipulátoři . připojit ( obslužný program ) def handle_car ( self , car ): pro handler in self . psovodi : psovod ( auto ) if __name__ == '__main__' : garáž = Garáž ( manipulátory ) auto = Auto () garáž . handle_car ( auto )

Odkazy

Poznámky

  1. Řetězec odpovědnosti v Delphi