Ansvarskedja

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 27 juli 2013; kontroller kräver 27 redigeringar .
Ansvarskedja
Ansvarskedja
Sorts beteendemässiga
Ändamål för organisation i systemet med ansvarsnivåer
Relaterade mallar länk
Beskrivs i Design Patterns Ja

Ansvarskedja är ett  beteendedesignmönster utformat för att organisera ansvarsnivåer i ett system.

Applikation

Mallen rekommenderas för användning under följande förhållanden:

Exempel

Delphi exempel

Källkod i Delphi enhetsmönster ; _ gränssnitt använder SysUtils ; typ TPurchase = klass offentligt nummer : heltal ; Belopp : Dubbel ; Syfte : sträng _ konstruktor Skapa ( antal : heltal ; am : Dubbel ; pur : sträng ) ; slut ; IApprover = gränssnitt [ '{3ACA3967-FFCF-48A1-AC45-9A9B98A8DD96}' ] procedur SetSuccessor ( efterföljare : IApprover ) ; procedur ProcessRequest ( köp : TPurchase ) ; slut ; TApprover = klass ( TInterfacedObject , IApprover ) skyddad FSuccessor : IApprover ; offentligt förfarande SetSuccessor ( efterträdare : IApprover ) ; procedur ProcessRequest ( köp : TPurchase ) ; virtuell ; abstrakt ; slut ; TDirector = klass ( TAProver ) procedur ProcessRequest ( köp : TPurchase ) ; åsidosätta ; slut ; TVicePresident = klass ( TApprover ) process ProcessRequest ( köp : TPurchase ) ; åsidosätta ; slut ; TPresident = class ( TAProver ) process ProcessRequest ( köp : TPurchase ) ; åsidosätta ; slut ; genomförande { TApprover } procedur TApprover . SetSuccessor ( efterföljare : IApprover ) ; börja FSuccessor := efterföljare ; slut ; { TDirektor } procedur TDirektor . ProcessRequest ( köp : TPurchase ) ; börja om köp . Belopp < 1 000 0,0 sedan WriteLn ( Format ( 'Regitor godkänd begäran # %d' , [ köp . Antal ])) annars om FSuccessor <> noll FSuccessor . ProcessRequest ( köp ) ; slut ; {TVicePresident} förfarande TV:s vicepresident . ProcessRequest ( köp : TPurchase ) ; börja om köp . Belopp < 2500 0,0 sedan WriteLn ( Format ( 'Vicepresident godkänd begäran # %d' , [ köp . Antal ])) annars om FSuccessor <> noll FSuccessor . ProcessRequest ( köp ) ; slut ; {TPresident} förfarande TPresident . ProcessRequest ( köp : TPurchase ) ; börja om köp . Belopp < 10000 0,0 sedan WriteLn ( Format ( 'President godkänd begäran # %d' , [ köp . Antal ])) annars WriteLn ( Format ( 'Request# %d kräver ett exekutivt möte!' , [ köp . Antal ])) slut ; { TPurchase } konstruktör TPurchase . Skapa ( antal : heltal ; am : Dubbel ; pur : sträng ) ; beginNumber : = num ; Belopp := am ; Syfte := pur ; slut ; slut . //________________________________________________________________________________ program Beteende . ChainOfResponsibility . mönster ; {$APPTYPE KONSOL} använder SysUtils , Pattern i 'Pattern.pas' ; varDirector : IApprover ; _ Vicepresident : I Godkännare ; President : Jag godkänner ; Inköp : TPurchase ; begin ReportMemoryLeaksOnShutDown := DebugHook <> 0 ; prova Director := TDirector . skapa ; Vicepresident := TV: s vicepresident . skapa ; President := TPresident . skapa ; tryDirector . _ SetSuccessor ( viceordförande ) ; Vicepresident . SetSuccessor ( president ) ; Köp := TPköp . Skapa ( 2034 , 35 0,00 , 'Supplies' ) ; regissör . ProcessRequest ( Inköp ) ; Köp . Gratis ; Köp := TPköp . Skapa ( 2035 , 3259 0.10 , 'Projekt X' ) ; regissör . ProcessRequest ( Inköp ) ; Köp . Gratis ; Köp := TPköp . Skapa ( 2036 , 12210 0,00 , 'Projekt Y' ) ; regissör . ProcessRequest ( Inköp ) ; Läsln ; Äntligen köp . Gratis ; slut ; förutom E : Exception do Writeln ( E. Classname , ' : ' , E. Message ) ; slut ; slut .

PHP 5 exempel

Källkod i PHP 5.3 namnområde ChainOfResponsibility { abstrakt klass Logger { constERR = 3 ; _ const NOTICE = 5 ; const DEBUG = 7 ; skyddad $mask ; // Nästa element i kedjan av ansvar skyddade $next ; offentlig funktion __construct ( $mask ) { $this -> mask = $mask ; } public function setNext ( Logger $log ) { $this -> next = $log ; returnera $log ; } public function message ( $msg , $priority ) { if ( $priority <= $this -> mask ) { $this -> writeMessage ( $msg ); } if ( $this -> next != null ) { $this -> next -> meddelande ( $msg , $priority ); } } skyddad abstrakt funktion writeMessage ( $msg ); } class StdoutLogger utökar Logger { skyddad funktion writeMessage ( $msg ) { echo sprintf ( "Skriver till stdout:%s \n " , $msg ); } } class EmailLogger utökar Logger { skyddad funktion writeMessage ( $msg ) { echo sprintf ( "Skicka via e-post:%s \n " , $msg ); } } class StderrLogger utökar Logger { skyddad funktion writeMessage ( $msg ) { echo sprintf ( "Skicka till stderr:%s \n " , $msg ); } } //ansvarskedja klass ChainOfResponsibilityExample { public function run () { // bygga ansvarskedjan $logger = new StdoutLogger ( Logger :: DEBUG ); $logger1 = $logger -> setNext ( ny EmailLogger ( Logger :: NOTICE )); $logger2 = $logger1 -> setNext ( ny StderrLogger ( Logger :: ERR )); // Hanteras av StdoutLogger $logger -> meddelande ( "Kommer in på funktion y." , Logger :: DEBUG ); // Hanteras av StdoutLogger och EmailLogger $logger -> meddelande ( "Steg 1 slutfört." , Logger :: NOTICE ); // Hanteras av alla tre loggare $logger -> meddelande ( "Ett fel har inträffat." , Logger :: ERR ); } } $chain = new ChainOfResponsibilityExample (); $kedja -> kör (); }

Java-exempel

Java -källa paket chainofresp ; abstrakt klass Logger { public static int ERR = 3 ; public static int NOTICE = 5 ; public static int DEBUG = 7 ; skyddad intmask ; _ // Nästa element i ansvarskedjan skyddade Logger nästa ; public Logger setNext ( Logger log ) { next = log ; returlogg ; _ } public void message ( String msg , int priority ) { if ( prioritet <= mask ) { writeMessage ( msg ); } if ( nästa != null ) { nästa . meddelande ( medd. , prioritet ); } } abstrakt skyddad void writeMessage ( String msg ); } class StdoutLogger utökar Logger { public StdoutLogger ( int mask ) { detta . mask = mask ; } protected void writeMessage ( String msg ) { System . ut . println ( "Skriver till stdout: " + msg ); } } class EmailLogger utökar Logger { public EmailLogger ( int mask ) { this . mask = mask ; } protected void writeMessage ( String msg ) { System . ut . println ( "Skicka via e-post: " + msg ); } } class StderrLogger utökar Logger { public StderrLogger ( int mask ) { detta . mask = mask ; } protected void writeMessage ( String msg ) { System . ut . println ( "Skicka till stderr: " + msg ); } } public class ChainOfResponsibilityExample { public static void main ( String [] args ) { // Bygg ansvarskedjan Logger logger , logger1 , logger2 ; logger = new StdoutLogger ( logger . DEBUG ); logger1 = logger . setNext ( ny EmailLogger ( logger . MEDDELANDE )); logger2 = logger1 . setNext ( ny StderrLogger ( Logger . ERR )); // Hanteras av StdoutLogger- logger . meddelande ( "Kommer in på funktion y." , Logger . DEBUG ); // Hanteras av StdoutLogger och EmailLogger logger . meddelande ( "Steg 1 slutfört." , Logger . NOTICE ); // Hanteras av alla tre loggare . meddelande ( "Ett fel har inträffat." , Logger . ERR ); } } /* Utdata är: Skriver till stdout: Går in på funktion y. Skriva till stdout: Steg 1 slutfört. Skickar via e-post: Steg 1 slutfört. Skriver till stdout: Ett fel har uppstått. Skickar via e-post: Ett fel har uppstått. Skickar till stderr: Ett fel har uppstått. */

Exempel i C#

Källtext i C# // Ansvarskedjans mönster -- Strukturellt exempel använder System ; namnutrymme DoFactory.GangOfFour.Chain.Structural { /// <sammanfattning> /// MainApp-startklass för Structural /// Chain of Responsibility Design Pattern. /// </summary> class MainApp { /// <summary> /// Ingångspunkt till konsolapplikationen. /// </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 ); // Generera och bearbeta begäran int [] requests = { 2 , 5 , 14 , 22 , 18 , 3 , 27 , 20 }; foreach ( int request in requests ) { h1 . HandleRequest ( förfrågan ); } // Vänta på användarkonsolen . ReadKey (); } } /// <summary> /// Abstraktklassen 'Handler' /// </summary> abstrakt klass Handler { protected Handler successor ; public void SetSuccessor ( hanterare efterföljare ) { detta . efterträdare = efterträdare ; } public abstract void HandleRequest ( int request ); } /// <summary> /// Klassen 'ConcreteHandler1' /// </summary> klassen ConcreteHandler1 : Handler { public override void HandleRequest ( int request ) { if ( request >= 0 && request < 10 ) { Console . WriteLine ( "{0} hanterade begäran {1}" , denna . GetType (). Namn , begäran ); } else if ( successor != null ) { successor . HandleRequest ( förfrågan ); } } } /// <summary> /// Klassen 'ConcreteHandler2' /// </summary> klassen ConcreteHandler2 : Handler { public override void HandleRequest ( int request ) { if ( request >= 10 && request < 20 ) { Console . WriteLine ( "{0} hanterade begäran {1}" , denna . GetType (). Namn , begäran ); } else if ( successor != null ) { successor . HandleRequest ( förfrågan ); } } } /// <summary> /// 'ConcreteHandler3'-klassen /// </summary> -klassen ConcreteHandler3 : Handler { public override void HandleRequest ( int request ) { if ( request >= 20 && request < 30 ) { Console . WriteLine ( "{0} hanterade begäran {1}" , denna . GetType (). Namn , begäran ); } else if ( successor != null ) { successor . HandleRequest ( förfrågan ); } } } } Output ConcreteHandler1 hanterade förfrågan 2 ConcreteHandler1 hanterade förfrågan 5 ConcreteHandler2 hanterade förfrågan 14 ConcreteHandler3 hanterade förfrågan 22 ConcreteHandler2 hanterade förfrågan 18 ConcreteHandler1 hanterade förfrågan 3 ConcreteHandler3 behandlade förfrågan 27 ConcreteHandler3 hanterade förfrågan 20

C++ exempel

Källtext i C++ #include <iostream> /** * Hjälparklass som beskriver något brott */ klass CriminalAction { vänklass Polis ; _ // Polisen har tillgång till materialet i utredningen int komplexitet ; // Fallets komplexitet const char * beskrivning ; // Kort beskrivning av brottet offentliga : CriminalAction ( int complexity , const char * description ) : komplexitet ( komplexitet ), beskrivning ( beskrivning ) {} }; /** * En abstrakt polis som kan utreda brott */ klass polis { skyddad : int reduktion ; // avdrag (förmågan att reda ut komplexa fall) för denna polis Polisman * nästa ; // en skickligare polis som får ett ärende om det är för jobbigt för den nuvarande virtuellt void undersökConcrete ( const char * description ) {} // faktisk undersökning offentliga : Polisman ( int avdrag ) : avdrag ( avdrag ), nästa ( nullptr ) {} virtuell ~ Polis () { ta bort nästa ; } /** * Lägger till en mer erfaren polis i ansvarskedjan som kan ta över * utredningen om den nuvarande misslyckas */ Polisman * setNext ( Polisman * polisman ) { nästa = polisman ; återvända nästa ; } /** * Polismannen inleder en utredning eller, om ärendet är för komplicerat, lämnar han det vidare till en mer erfaren kollega */ void undersöka ( CriminalAction * criminalAction ) { if ( deduktion < criminalAction -> komplexitet ) { if ( nästa ) { nästa -> undersöka ( criminalAction ); } annat { std :: cout << "Detta fall ska inte avslöjas för någon." << std :: endl ; } } annat { undersöka Concrete ( kriminellAction -> description ); } } }; klass MartinRiggs : offentlig polis { skyddad : void investigateConcrete ( const char * description ) { std :: cout << "Utredning av ärendet \" " << beskrivning << " \" ledd av sergeant Martin Riggs" << std :: endl ; } offentliga : MartinRiggs ( int avdrag ) : Polis ( avdrag ) {} }; klass JohnMcClane : offentlig polis { skyddad : void investigateConcrete ( const char * description ) { std :: cout << "Utredning \" " << beskrivning << " \" Detektiv John McClane" << std :: endl ; } offentliga : JohnMcClane ( int avdrag ) : Polis ( avdrag ) {} }; klass Vincent Hanna : offentlig polis { skyddad : void investigateConcrete ( const char * description ) { std :: cout << "Utredning av ärendet \" " << beskrivning << " \" ledd av löjtnant Vincent Hanna" << std :: endl ; } offentliga : VincentHanna ( int avdrag ) : Polis ( avdrag ) {} }; int main () { std :: cout << "OUTPUT:" << std :: endl ; Polis * polis = ny MartinRiggs ( 3 ); // polis med minst undersökande skicklighet polis -> setNext ( ny JohnMcClane ( 5 )) -> setNext ( ny Vincent Hanna ( 8 )); // lägg till två erfarna poliskollegor till honom -> undersök ( ny CriminalAction ( 2 , "Droghandel från Vietnam" )); polisman -> undersöka ( ny CriminalAction ( 7 , "Ett vågat bankrån i centrala Los Angeles" )); polisman -> undersöka ( ny CriminalAction ( 5 , "Series of explosions in downtown New York" )); returnera 0 ; } /** * OUTPUT: * Undersöker narkotikahandeln i Vietnam av sergeant Martin Riggs * Undersöker djärvt bankrån i centrala Los Angeles av löjtnant Vincent Hanna * Undersöker en serie bombdåd i centrala New York med detektiv John McClain som värd */

Python-exempel

Källkod i Python hanterare = [] def car_handler ( func ): hanterare . lägga till ( func ) returnera func klass Bil : def __init__ ( själv ): själv . namn = Inget själv . km = 11100 själv . bränsle = 5 själv . olja = 5 @car_handler def handle_fuel ( bil ): om bil . bränsle < 10 : print ( "tillsatt bränsle" ) bil . bränsle = 100 @car_handler def handle_km ( bil ): om bil . km > 10000 : print ( "gjort ett biltest." ) bil . km = 0 @car_handler def handle_oil ( bil ): om bil . olja < 10 : print ( "Tillsatt olja" ) bil . olja = 100 klass Garage : def __init__ ( själv , hanterare = Inga ): själv . hanterare = hanterare eller [] def add_handler ( själv , hanterare ): själv . hanterare . lägga till ( hanterare ) def handle_car ( själv , bil ): för hanterare i själv . hanterare : hanterare ( bil ) om __name__ == '__main__' : garage = Garage ( hanterare ) bil = Bil ( ) garage . handle_car ( bil )

Länkar

Anteckningar

  1. Ansvarskedja i Delphi