Lanțul de responsabilități

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 27 iulie 2013; verificările necesită 27 de modificări .
Lanțul de responsabilități
Lanț de responsabilitate
Tip de comportamental
Scop pentru organizarea în sistemul de niveluri de responsabilitate
Șabloane înrudite linker
Descris în Design Patterns da

Lanțul de responsabilitate este un  model de design comportamental conceput pentru a organiza nivelurile de responsabilitate într-un sistem.

Aplicație

Șablonul este recomandat pentru utilizare în următoarele condiții:

Exemple

Exemplu Delphi

Cod sursă în Delphi unitPattern ; _ interfata folosește SysUtils ; tip TPurchase = clasă public Număr : întreg ; Suma : dubla ; Scop : șir _ constructor Create ( num : integer ; am : Double ; pur : string ) ; sfârşitul ; IApprover = interfață [ '{3ACA3967-FFCF-48A1-AC45-9A9B98A8DD96}' ] procedura SetSuccessor ( succesor : IApprover ) ; procedura ProcessRequest ( cumpărare : TPurchase ) ; sfârşitul ; TApprover = clasa ( TInterfacedObject , IApprover ) protejat FSuccessor : IApprover ; procedura publică SetSuccessor ( succesor : IApprover ) ; procedura ProcessRequest ( cumpărare : TPurchase ) ; virtual ; abstract ; sfârşitul ; TDirector = procedură de clasă ( TApprover ) ProcessRequest ( cumpărare : TPurchase ) ; suprascrie ; sfârşitul ; TVicePresident = procedură de clasă ( TAApprover ) ProcessRequest ( cumpărare : TPurchase ) ; suprascrie ; sfârşitul ; TPresident = procedură de clasă ( TApprover ) ProcessRequest ( cumpărare : TPurchase ) ; suprascrie ; sfârşitul ; implementare { TApprover } procedura TAApprover . SetSuccessor ( succesor : IApprover ) ; începe FSuccessor := succesor ; sfârşitul ; { TDirector } procedura TDirector . ProcessRequest ( cumpărare : TPurchase ) ; începe dacă cumpărare . Sumă < 1000 0,0 apoi WriteLn ( Format ( 'Solicitare aprobată de director # %d' , [ cumpărare . Număr ])) altfel dacă FSuccessor <> nil , atunci FSuccessor . ProcessRequest ( cumpărare ) ; sfârşitul ; {TVice President} procedura TVicePreședinte . ProcessRequest ( cumpărare : TPurchase ) ; începe dacă cumpără . Sumă < 2500 0,0 apoi WriteLn ( Format ( 'Solicitare aprobată de vicepreședinte # %d' , [ cumpărare . Număr ])) altfel dacă FSuccessor <> nil atunci FSuccessor . ProcessRequest ( cumpărare ) ; sfârşitul ; {TPresident} procedura TPreședinte . ProcessRequest ( cumpărare : TPurchase ) ; începe dacă cumpără . Sumă < 10000 0,0 apoi WriteLn ( Format ( 'Președintele a aprobat cererea # %d' , [ cumpărare . Număr ])) altfel WriteLn ( Format ( 'Solicitarea # %d necesită o întâlnire executivă!' , [ cumpărare . Număr ])) final ; { Achiziționare } constructor TPurchase . Creați ( num : întreg ; am : Double ; pur : șir ) ; beginNumber : = num ; Suma := am ; Scop := pur ; sfârşitul ; sfârşitul . //________________________________________________________________________ program Comportamental . ChainOfResponsibility . model ; {$APPTYPE CONSOLE} folosește SysUtils , Pattern în 'Pattern.pas' ; varDirector : IApprover ; _ Vicepreşedinte : I Aprobator ; Președinte : I Aprobator ; Cumpărare : Tpurchase ; începe ReportMemoryLeaksOnShutDown := DebugHook <> 0 ; încercați Director := TDirector . a crea ; Vicepreședinte := TVicePresident . a crea ; Președinte := TPreședinte . a crea ; încercați Director _ SetSuccessor ( vicepresedinte ) ; Vicepreședinte . SetSuccessor ( Președinte ) ; Cumpărare := TCumparare . Creați ( 2034 , 35 0,00 , „Rechizite” ) ; director . ProcessRequest ( Cumpărare ) ; Achizitioneaza . Gratuit ; Cumpărare := TCumparare . Creați ( 2035 , 3259 0,10 , „Proiect X” ) ; director . ProcessRequest ( Cumpărare ) ; Achiziționare . Gratuit ; Cumpărare := TCumparare . Creați ( 2036 , 12210 0,00 , „Proiect Y” ) ; director . ProcessRequest ( Cumpărare ) ; Readln ; În sfârșit Cumpărați . Gratuit ; sfârşitul ; cu excepția E : Excepție pentru Writeln ( E. Classname , ' : ' , E. Message ) ; sfârşitul ; sfârşitul .

Exemplu PHP 5

Cod sursă în PHP 5.3 spațiu de nume ChainOfResponsibility { clasa abstractă Logger { constERR = 3 ; _ const NOTIFICARE = ​​5 ; const DEBUG = 7 ; protected $mask ; // Următorul element din lanțul de responsabilități protejat $next ; function public __construct ( $mask ) { $this -> mask = $mask ; } public function setNext ( Logger $log ) { $this -> next = $log ; returnează $log ; } mesaj public function ( $msg , $priority ) { if ( $priority <= $this -> mask ) { $this -> writeMessage ( $msg ); } if ( $this -> next != null ) { $this -> next -> mesaj ( $msg , $priority ); } } funcția abstractă protejată writeMessage ( $msg ); } clasa StdoutLogger extinde Logger { protected function writeMessage ( $msg ) { echo sprintf ( "Scrierea in stdout:%s \n " , $msg ); } } clasa EmailLogger extinde Logger { protected function writeMessage ( $msg ) { echo sprintf ( "Trimit prin email:%s \n " , $msg ); } } clasa StderrLogger extinde Logger { protected function writeMessage ( $msg ) { echo sprintf ( "Trimiterea catre stderr:%s \n " , $msg ); } } //lanțul de responsabilități clasa ChainOfResponsibilityExample { public function run () { // construiește lanțul de responsabilitate $logger = new StdoutLogger ( Logger :: DEBUG ); $logger1 = $logger -> setNext ( nou EmailLogger ( Logger :: NOTIFICARE )); $logger2 = $logger1 -> setNext ( nou StderrLogger ( Logger :: ERR )); // Gestionat de StdoutLogger $logger -> mesaj ( "Se introduce funcția y." , Logger :: DEBUG ); // Gestionat de StdoutLogger și EmailLogger $logger -> mesaj ( "Step1 completed." , Logger :: NOTIFICARE ); // Gestionat de toți cei trei loggeri $logger -> mesaj ( „A apărut o eroare.” , Logger :: ERR ); } } $chain = nou ChainOfResponsibilityExample (); $lant -> rula (); }

Exemplu Java

Sursa Java pachet chainofresp ; abstract class Logger { public static int ERR = 3 ; public static int NOTIFICARE = ​​5 ; public static int DEBUG = 7 ; intmask protejat ; _ // Următorul element din lanțul de responsabilitate protejat Logger next ; public Logger setNext ( Logger log ) { next = log ; jurnal de returnare ; } mesaj public void ( String msg , int priority ) { if ( priority <= mask ) { writeMessage ( msg ); } if ( next != null ) { next . mesaj ( msj , prioritate ); } } abstract protejat void writeMessage ( String msg ); } clasa StdoutLogger extinde Logger { public StdoutLogger ( int mask ) { this . masca = masca ; } protejat void writeMessage ( String msg ) { System . afară . println ( "Scrierea la stdout: " + msg ); } } clasa EmailLogger extinde Logger { public EmailLogger ( int mask ) { this . masca = masca ; } protejat void writeMessage ( String msg ) { System . afară . println ( "Trimitere prin e-mail: " + msg ); } } clasa StderrLogger extinde Logger { public StderrLogger ( int mask ) { this . masca = masca ; } protejat void writeMessage ( String msg ) { System . afară . println ( "Se trimite la stderr: " + msg ); } } public class ChainOfResponsibilityExample { public static void main ( String [] args ) { // Construiește lanțul de responsabilitate Logger logger , logger1 , logger2 ; logger = new StdoutLogger ( Logger . DEBUG ); logger1 = logger . setNext ( nou EmailLogger ( Logger . NOTIFICARE )); logger2 = logger1 . setNext ( nou StderrLogger ( Logger . ERR )); // Gestionat de StdoutLogger logger . mesaj ( „Se introduce funcția y.” , Logger . DEBUG ); // Gestionat de StdoutLogger și EmailLogger logger . mesaj ( „Step1 completed.” , Logger . NOTIFICARE ); // Gestionat de toate cele trei logger-uri . mesaj ( „A apărut o eroare.” , Logger . ERR ); } } /* Ieșirea este: Scrierea în stdout: Se introduce funcția y. Scriere la stdout: Pasul 1 finalizat. Trimiterea prin e-mail: Pasul 1 finalizat. Scriere la stdout: a apărut o eroare. Se trimite prin e-mail: a apărut o eroare. Se trimite la stderr: a apărut o eroare. */

Exemplu în C#

Text sursă în C# // Modelul lanțului de responsabilitate -- Exemplu structural folosind System ; namespace DoFactory.GangOfFour.Chain.Structural { /// <summary> /// Clasa de pornire MainApp pentru Structural /// Chain of Responsibility Design Pattern. /// </summary> class MainApp { /// <summary> /// Punct de intrare în aplicația consolă. /// </summary> static void Main () { // Setup Chain of Responsibility Handler h1 = new ConcreteHandler1 (); Handler h2 = nou ConcreteHandler2 (); Handler h3 = nou ConcreteHandler3 (); h1 . SetSuccessor ( h2 ); h2 . SetSuccessor ( h3 ); // Generați și procesați cererea int [] cereri = { 2 , 5 , 14 , 22 , 18 , 3 , 27 , 20 }; foreach ( cerere int în cereri ) { h1 . HandleRequest ( cerere ); } // Așteptați Consola utilizatorului . ReadKey (); } } /// <summary> /// Clasa abstractă 'Handler' /// </summary> abstract class Handler { protected Handler succesor ; public void SetSuccessor ( succesorul Handlerului ) { this . succesor = succesor ; } public abstract void HandleRequest ( cerere int ); } /// <summary> /// Clasa „ConcreteHandler1” /// </summary> clasa ConcreteHandler1 : Handler { public override void HandleRequest ( int cerere ) { if ( request >= 0 && request < 10 ) { Console . WriteLine ( „{0} a gestionat cererea {1}” , aceasta . GetType (). Nume , cerere ); } else if ( succesor != null ) { succesor . HandleRequest ( cerere ); } } } /// <summary> /// Clasa „ConcreteHandler2” /// </summary> clasa ConcreteHandler2 : Handler { public override void HandleRequest ( int cerere ) { if ( request >= 10 && request < 20 ) { Console . WriteLine ( „{0} a gestionat cererea {1}” , aceasta . GetType (). Nume , cerere ); } else if ( succesor != null ) { succesor . HandleRequest ( cerere ); } } } /// <summary> /// Clasa „ConcreteHandler3” /// </summary> clasa ConcreteHandler3 : Handler { public override void HandleRequest ( int cerere ) { if ( request >= 20 && request < 30 ) { Console . WriteLine ( „{0} a gestionat cererea {1}” , aceasta . GetType (). Nume , cerere ); } else if ( succesor != null ) { succesor . HandleRequest ( cerere ); } } } } Ieșire ConcreteHandler1 gestionată cerere 2 ConcreteHandler1 gestionată cerere 5 ConcreteHandler2 gestionată cerere 14 ConcreteHandler3 gestionată cerere 22 ConcreteHandler2 gestionată cerere 18 ConcreteHandler1 gestionată cerere 3 ConcreteHandler3 gestionată cerere 27 ConcreteHandler3 gestionată cerere 20

Exemplu C++

Text sursă în C++ #include <iostream> /** * Clasa de ajutor care descrie o crimă */ clasa CriminalAction { friend class polițist ; // Poliția are acces la materialele anchetei int complexitate ; // Complexitatea cazului const char * descriere ; // Scurtă descriere a infracțiunii public : CriminalAction ( int complexity , const char * description ) : complexitate ( complexitate ), descriere ( descriere ) {} }; /** * Un ofițer de poliție abstract care poate investiga crime */ polițist de clasă { protejat : int reducere ; // deducere (capacitatea de a dezlega cazuri complexe) pentru acest polițist Poliţist * următor ; // un polițist mai priceput care va primi un caz dacă este prea greu pentru cel actual virtual void investigateConcrete ( const char * description ) {} // investigație reală public : Poliţist ( int deducere ) : deducere ( deducere ), următor ( nullptr ) {} virtual ~ Polițist () { șterge următorul ; } /** * Adaugă în lanțul de responsabilitate un polițist mai experimentat care poate prelua * ancheta dacă cea actuală eșuează */ Poliţist * setNext ( Poliţist * poliţist ) { următor = polițist ; reveniți în continuare ; } /** * Polițistul începe o anchetă sau, dacă cazul este prea complicat, o transmite unui coleg mai experimentat */ nul investigare ( CriminalAction * criminalAction ) { if ( deducere < actiune penala -> complexitate ) { dacă ( următorul ) { următorul -> investigați ( Acțiune penală ); } altfel { std :: cout << "Acest caz nu trebuie dezvăluit nimănui." << std :: endl ; } } altfel { investigateBeton ( criminalAction -> description ); } } }; clasa MartinRiggs : polițist public { protejat : void investigateConcrete ( const char * description ) { std :: cout << "Investigarea cazului \" " << descriere << " \" condus de sergent Martin Riggs" << std :: endl ; } public : MartinRiggs ( deducție int ) : polițist ( deducere ) {} }; clasa JohnMcClane : polițist public { protejat : void investigateConcrete ( const char * description ) { std :: cout << "Investigație \" " << descriere << " \" Detectivul John McClane" << std :: endl ; } public : JohnMcClane ( deducție int ) : polițist ( deducere ) {} }; clasa Vincent Hanna : polițist public { protejat : void investigateConcrete ( const char * description ) { std :: cout << "Investigarea cazului \" " << descriere << " \" condusa de locotenentul Vincent Hanna" << std :: endl ; } public : VincentHanna ( deducție int ) : polițist ( deducere ) {} }; int main () { std :: cout << "OUTPUT:" << std :: endl ; Polițist * polițist = nou MartinRiggs ( 3 ); // polițist cu cea mai mică abilitate de investigare polițist -> setNext ( JohnMcClane nou ( 5 )) -> setNext ( nou Vincent Hanna ( 8 )); // adaugă lui doi colegi polițiști cu experiență -> investigați ( nou CriminalAction ( 2 , „Trafic de droguri din Vietnam” )); polițist -> investigați ( nou CriminalAction ( 7 , „Un jaf de bancă îndrăzneț în centrul orașului Los Angeles” )); polițist -> investigați ( nou CriminalAction ( 5 , „Seria de explozii în centrul orașului New York” )); returnează 0 ; } /** * REZULTARE: * Investigarea traficului de droguri în Vietnam de către sergentul Martin Riggs * Investigarea jafului îndrăzneț al băncii din centrul orașului Los Angeles de către locotenentul Vincent Hanna * Investigarea unei serii de atentate cu bombă în centrul orașului New York, găzduite de detectivul John McClain */

Exemplu Python

Cod sursă în Python handler = [] def car_handler ( func ): handler . append ( func ) return func clasa Car : def __init__ ( self ): self . nume = None self . km = 11100 auto . combustibil = 5 auto . ulei = 5 @car_handler def handle_fuel ( mașină ): dacă mașină . combustibil < 10 : imprimare ( „combustibil adăugat” ) mașină . combustibil = 100 @car_handler def handle_km ( mașină ): dacă mașină . km > 10000 : imprimare ( „a făcut un test de mașină.” ) mașină . km = 0 @car_handler def handle_oil ( mașină ): dacă mașină . ulei < 10 : imprimare ( „Ulei adăugat” ) mașină . ulei = 100 clasa Garaj : def __init__ ( self , handlers = None ): self . handlers = handlers sau [] def add_handler ( self , handler ): self . manipulatori . anexează ( handler ) def handle_car ( self , car ): pentru handler in self . handlers : handler ( masina ) if __name__ == '__main__' : garage = Garage ( handlers ) car = Car () garage . handle_car ( masina )

Link -uri

Note

  1. Lanțul de responsabilitate în Delphi