Felelősségi lánc
Az oldal jelenlegi verzióját még nem nézték át tapasztalt közreműködők, és jelentősen eltérhet a 2013. július 27-én felülvizsgált
verziótól ; az ellenőrzések 27 szerkesztést igényelnek .
Felelősségi lánc |
---|
Felelősségi lánc |
|
Típusú |
viselkedési |
Célja |
a felelősségi szintek rendszerében való szervezésért |
Kapcsolódó sablonok |
linker |
Leírása: Tervezési minták |
Igen |
A felelősségi lánc egy viselkedési tervezési minta , amelyet a felelősségi szint megszervezésére terveztek egy rendszerben
.
Alkalmazás
A sablon használata a következő körülmények között javasolt:
- a kifejlesztett rendszerben van egy objektumcsoport, amely képes feldolgozni egy bizonyos típusú üzenetet;
- minden üzenetet legalább egy rendszerobjektumnak fel kell dolgoznia;
- A rendszerben lévő üzenetek feldolgozása a „dolgozd fel magad vagy továbbítsd másnak” séma szerint történik, vagyis egyes üzenetek feldolgozása azon a szinten történik, ahol érkezett, míg mások más szintű objektumokhoz kerülnek.
Példák
Delphi példa
Forráskód
Delphiben
egységminta ; _
felület
SysUtils-t használ ;
típus
TPurchase = class
public
Szám : integer ;
Mennyiség : Dupla ;
Cél : karakterlánc _
konstruktor Create ( szám : egész szám ; am : Double ; pur : string ) ;
vége ;
IApprover = interfész
[ '{3ACA3967-FFCF-48A1-AC45-9A9B98A8DD96}' ]
eljárás SetSuccessor ( utódja : IApprover ) ;
eljárás ProcessRequest ( vásárlás : TVásárlás ) ;
vége ;
TApprover = osztály ( TInterfacedObject , IApprover )
védett
FSutcossor : IApprover ;
nyilvános
eljárás SetSuccessor ( utód : IApprover ) ;
eljárás ProcessRequest ( vásárlás : TVásárlás ) ; virtuális ; absztrakt ;
vége ;
TDirector = osztály ( TApprover )
eljárás ProcessRequest ( vásárlás : TPurchase ) ; felülbírálni ;
vége ;
TVicePresident = osztály ( TAprover )
eljárás ProcessRequest ( vásárlás : Tvásárlás ) ; felülbírálni ;
vége ;
TPresident = osztály ( TAprover )
eljárás ProcessRequest ( vásárlás : TVásárlás ) ; felülbírálni ;
vége ;
végrehajtás
{ TJóváhagyó }
eljárás TJóváhagyó . SetSuccessor ( utód : IApprover ) ;
begin
FSuccessor := utód ;
vége ;
{ TDirector }
eljárás TDirector . ProcessRequest ( vásárlás : TVásárlás ) ;
vásárlás esetén kezdődik
. Összeg < 1000 0.0 , akkor WriteLn ( Formátum ( 'Az igazgató által jóváhagyott kérelem # %d' , [ vásárlás . Szám ])) különben ha FSutód <> null , akkor FSutód . ProcessRequest ( vásárlás ) ; vége ;
{TVicePresident}
eljárás TViceElnök . ProcessRequest ( vásárlás : TVásárlás ) ;
kezdődik
, ha vásárol . Összeg < 2500 0,0 akkor
WriteLn ( Formátum ( 'Alelnök jóváhagyott kérelem # %d' , [ vásárlás . Szám ]))
különben ha FSuttóda <> nulla , akkor
FSuttó . ProcessRequest ( vásárlás ) ;
vége ;
{TPelnök}
eljárás TElnök . ProcessRequest ( vásárlás : TVásárlás ) ;
vásárlás esetén kezdődik
. Összeg < 10000 0,0 , majd WriteLn ( Formátum ( 'Elnök által jóváhagyott kérelem # %d' , [ vásárlás . Szám ])) else WriteLn ( Formátum ( 'A %d. számú kérelem vezetői értekezletet igényel!' , [ vásárlás . Szám ])) vége ;
{ TVásárlás }
konstruktor TVásárlás . Create ( num : integer ; am : Double ; pur : string ) ;
beginNumber
: = szám ; Összeg := am ; Cél := pur ; vége ;
vége .
//________________________________________________________________________________
program Viselkedési . Felelősségi lánc . minta ;
{$APPTYPE CONSOLE}
SysUtils ,
Pattern mintát használ a 'Pattern.pas'- ban ;
varDirector
: Iapprover ; _ Alelnök : I jóváhagyó ; Elnök : I Jóváhagyó ; Vásárlás : TVásárlás ;
begin
ReportMemoryLeaksOnShutDown := DebugHook <> 0 ;
próbáld meg
Director := TDirector . létrehozni ;
Alelnök := TVicePresident . létrehozni ; Elnök := TElnök . létrehozni ;
tryDirector
_ _ SetSuccessor ( alelnök ) ;
alelnök . SetSuccessor ( Elnök ) ;
Vásárlás := TVásárlás . Létrehozása ( 2034 , 35 0.00 , 'Kellékek' ) ;
igazgató . ProcessRequest ( Vásárlás ) ;
Vásárlás . Ingyenes ;
Vásárlás := TVásárlás . Létrehozás ( 2035 , 3259 0.10 , 'X projekt' ) ;
igazgató . ProcessRequest ( Vásárlás ) ;
Vásárlás . Ingyenes ;
Vásárlás := TVásárlás . Létrehozása ( 2036 , 12210 0,00 , 'Y projekt' ) ;
igazgató . ProcessRequest ( Vásárlás ) ;
Readln ;
Végül
Vásároljon . Ingyenes ;
vége ;
kivéve
E : Exception do Writeln ( E . Osztálynév , ' : ' , E . Üzenet ) ; vége ; vége .
PHP 5 példa
Forráskód
PHP 5.3 -ban
névtér ChainOfResponsibility {
absztrakt osztály Logger {
constERR = 3 ; _ const ÉRTESÍTÉS = 5 ; const DEBUG = 7 ;
védett $maszk ;
// A következő elem a felelősségi láncban
védett $next ;
public function __construct ( $maszk ) {
$this -> mask = $maszk ;
}
public function setNext ( Logger $log ) {
$this -> next = $log ;
return $log ;
}
public function üzenet ( $msg , $priority ) {
if ( $priority <= $this -> mask ) {
$this -> writeMessage ( $msg );
}
if ( $this -> next != null ) {
$this -> next -> message ( $msg , $priority );
}
}
védett absztrakt függvény writeMessage ( $msg );
}
class StdoutLogger kiterjeszti a Logger {
Protected function writeMessage ( $msg ) {
echo sprintf ( "Írás a következőhöz: stdout:%s \n " , $msg );
}
}
class EmailLogger kiterjeszti a naplózót {
protected function writeMessage ( $msg ) {
echo sprintf ( "Küldés e-mailben:%s \n " , $msg );
}
}
class StderrLogger kiterjeszti Logger {
Protected function writeMessage ( $msg ) {
echo sprintf ( "Küldés a következőnek: stderr:%s \n " , $msg );
}
}
//felelősségi lánc
osztály ChainOfResponsibilityExample {
public function run () {
// a felelősségi lánc felépítése
$logger = new StdoutLogger ( Logger :: DEBUG );
$logger1 = $logger -> setNext ( new EmailLogger ( Logger :: NOTICE ));
$logger2 = $logger1 -> setNext ( new StderrLogger ( Logger :: ERR ));
// StdoutLogger kezeli
$logger -> üzenet ( "Y függvény bevitele." , Logger :: DEBUG );
// StdoutLogger és EmailLogger kezeli
$logger -> üzenet ( "1. lépés befejezve." , Logger :: ÉRTESÍTÉS );
// Mindhárom naplózó kezeli
$logger -> üzenet ( "Hiba történt." , Logger :: ERR );
}
}
$lánc = new ChainOfResponsibilityExample ();
$lánc -> fut ();
}
Java példa
Java forrás
csomag chainofresp ;
absztrakt osztály Logger {
public static int ERR = 3 ;
public static int ÉRTESÍTÉS = 5 ;
public static int DEBUG = 7 ;
védett belső maszk ; _
// A felelősségi lánc következő eleme
védett Logger next ;
public Logger setNext ( naplózó napló ) {
next = log ;
visszatérési napló ;
}
public void message ( String msg , int priority ) {
if ( priority <= mask ) {
writeMessage ( msg );
}
if ( next != null ) {
next . üzenet ( üzenet , prioritás );
}
}
absztrakt védett void writeMessage ( String msg );
}
class StdoutLogger extends Logger {
public StdoutLogger ( int maszk ) {
this . maszk = maszk ;
}
protected void writeMessage ( String msg ) {
Rendszer . ki . println ( "Írás a stdoutba:" + msg );
}
}
class EmailLogger extends Logger {
public EmailLogger ( int maszk ) {
this . maszk = maszk ;
}
protected void writeMessage ( String msg ) {
Rendszer . ki . println ( "Küldés e-mailben: " + msg );
}
}
class StderrLogger expands Logger {
public StderrLogger ( int maszk ) {
this . maszk = maszk ;
}
protected void writeMessage ( String msg ) {
Rendszer . ki . println ( "Küldés az stderr-nek:" + msg );
}
}
public class ChainOfResponsibilityExample {
public static void main ( String [ ] args ) {
// A felelősségi lánc felépítése
Logger logger , logger1 , logger2 ;
logger = new StdoutLogger ( Logger . DEBUG );
logger1 = logger . setNext ( new EmailLogger ( Logger . NOTICE ));
logger2 = logger1 . setNext ( új StderrLogger ( Logger . ERR ));
// Az StdoutLogger
logger kezeli . üzenet ( "Belépés az y függvénybe." , Logger . DEBUG );
// Az StdoutLogger és az EmailLogger
logger kezeli . üzenet ( "1. lépés befejezve." , Napló . ÉRTESÍTÉS );
// Mindhárom logger kezeli
logger . üzenet ( "Hiba történt." , Logger . ERR );
}
}
/*
A kimenet a következő:
Írás stdoutba: y függvény bevitele.
Írás az stdoutba: Az 1. lépés befejeződött.
Küldés e-mailben: Az 1. lépés befejeződött.
Írás a stdoutba: Hiba történt.
Küldés e-mailben: Hiba történt.
Küldés a stderr-nek: Hiba történt.
*/
Példa C#-ban
Forrásszöveg
C# nyelven
// Felelősségi lánc minta -- Strukturális példa
a rendszer használatával ;
névtér DoFactory.GangOfFour.Chain.Structural
{
/// <summary>
/// MainApp indítási osztály a Structuralhoz
/// Chain of Responsibility Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Belépési pont a konzolalkalmazásba.
/// </summary>
static void Main ()
{
// Felelősségi lánc beállítása
h1 = new ConcreteHandler1 ( ); Handler h2 = új ConcreteHandler2 (); Handler h3 = új ConcreteHandler3 (); h1 . SetSuccessor ( h2 ); h2 . SetSuccessor ( h3 );
// Kérelem generálása és feldolgozása
int [] requests = { 2 , 5 , 14 , 22 , 18 , 3 , 27 , 20 };
foreach ( int kérés a kérésekben )
{
h1 . HandleRequest ( kérés );
}
// Várja meg a felhasználói
konzolt . ReadKey ();
}
}
/// <summary>
/// A 'Kezelő' abstract class
/// </summary>
abstract class Kezelő
{
protected Kezelő utódja ;
public void SetSuccessor ( kezelő utódja )
{
this . utód = utód ;
}
public abstract void HandleRequest ( int request );
}
/// <summary>
/// A 'ConcreteHandler1' osztály
/// </summary>
class ConcreteHandler1 : Handler
{
public override void HandleRequest ( int request )
{
if ( request >= 0 && request < 10 )
{
Console . WriteLine ( "{0} kezelt kérés {1}" ,
ez . GetType (). Név , kérés );
}
else if ( utód != null )
{
utód . HandleRequest ( kérés );
}
}
}
/// <summary>
/// A 'ConcreteHandler2' osztály
/// </summary>
class ConcreteHandler2 : Handler
{
public override void HandleRequest ( int request )
{
if ( request >= 10 && request < 20 )
{
Console . WriteLine ( "{0} kezelt kérés {1}" ,
ez . GetType (). Név , kérés );
}
else if ( utód != null )
{
utód . HandleRequest ( kérés );
}
}
}
/// <summary>
/// A 'ConcreteHandler3' osztály
/// </summary>
class ConcreteHandler3 : Handler
{
public override void HandleRequest ( int request )
{
if ( request >= 20 && request < 30 )
{
Console . WriteLine ( "{0} kezelt kérés {1}" ,
ez . GetType (). Név , kérés );
}
else if ( utód != null )
{
utód . HandleRequest ( kérés );
}
}
}
}
Output
ConcreteHandler1 kezelt kérés 2
ConcreteHandler1 kezelt kérelem 5
ConcreteHandler2 kezelt kérelem 14
ConcreteHandler3 kezelt kérelem 22
ConcreteHandler2 kezelt kérelem 18
ConcreteHandler1 kezelt kérelem 3
ConcreteHandler3 kezelt kérelem 27
ConcreteHandler 203 kezelt kérelem
C++ példa
Forrásszöveg
C++ nyelven
#include <iostream>
/**
* Segítői osztály valamilyen bűntény leírásával
*/
class Criminal Action {
barát osztály Rendőr ; // A rendőrség hozzáfér a nyomozás anyagaihoz
int komplexitás ; // Az ügy összetettsége
const char * leírás ; // A bűncselekmény rövid leírása
nyilvános :
Criminal Action ( int összetettség , const char * leírás ) : összetettség ( összetettség ), leírás ( leírás ) {}
};
/**
* Egy elvont rendőr, aki bűnügyeket tud nyomozni
*/
osztályos rendőr {
védett :
int redukció ; // levonás (az összetett esetek feloldásának képessége) ennek a rendőrnek
Rendőr * következő ; // ügyesebb zsaru, aki ügyet kap, ha túl nehéz a mostaninak
virtual void investigateConcrete ( const char * description ) {} // tényleges vizsgálat
nyilvános :
Rendőr ( int levonás ) : levonás ( levonás ), következő ( nullptr ) {}
virtuális ~ Rendőr () {
következő törlése ;
}
/**
* Egy tapasztaltabb rendőrrel bővül a felelősségi lánc, aki átveheti
* a nyomozást, ha a jelenlegi sikertelen
*/
Rendőr * setNext ( Rendőr * rendőr ) {
következő = rendőr ;
visszatérés következő ;
}
/**
* A rendőr vizsgálatot indít, vagy ha az ügy túl bonyolult, átadja egy tapasztaltabb kollégának
*/
void kivizsgál ( CriminalAction * CriminalAction ) {
if ( levonás < bűncselekmény -> összetettség ) {
if ( következő ) {
next -> nyomoz ( kriminalAction );
} másik {
std :: cout << "Ezt az esetet senkinek nem szabad felfedni." << std :: endl ;
}
} másik {
vizsgáljaBeton ( kriminálAkció -> leírás );
}
}
};
osztály MartinRiggs : közrendőr { _
védett :
void investigateConcrete ( const char * leírás ) {
std :: cout << "Az ügy kivizsgálása \" " << leírás << " \" Martin Riggs őrmester vezette" << std :: endl ;
}
nyilvános :
MartinRiggs ( int levonás ) : Rendőr ( levonás ) {}
};
osztály JohnMcClane : közrendőr { _
védett :
void investigateConcrete ( const char * leírás ) {
std :: cout << "Vizsgálat \" " << leírás << " \" John McClane nyomozó" << std :: endl ;
}
nyilvános :
JohnMcClane ( int levonás ) : Rendőr ( levonás ) {}
};
osztály Vincent Hanna : közrendőr {
védett :
void investigateConcrete ( const char * leírás ) {
std :: cout << "Az ügy kivizsgálása \" " << leírás << " \" Vincent Hanna hadnagy vezette" << std :: endl ;
}
nyilvános :
VincentHanna ( int levonás ) : Rendőr ( levonás ) {}
};
int main () {
std :: cout << "OUTPUT:" << std :: endl ;
Rendőr * rendőr = új MartinRiggs ( 3 ); // legkevesebb nyomozási képességű rendőr rendőr
-> setNext ( új JohnMcClane ( 5 ))
-> setNext ( új Vincent Hanna ( 8 )); // adjunk hozzá két tapasztalt rendőr kollégát -> nyomoz ( new CriminalAction ( 2 , "Drog trade from Vietnam" ));
rendőr -> nyomozni ( új CriminalAction ( 7 , "Merész bankrablás Los Angeles belvárosában" ));
rendőr -> nyomoz ( új CriminalAction ( 5 , "Robbanások sorozata New York belvárosában" ));
return 0 ;
}
/**
* KIMENET:
* Martin Riggs őrmester a vietnami kábítószer-kereskedelem
vizsgálata * Vincent Hanna hadnagy által Los Angeles belvárosában elkövetett merész bankrablás
nyomozása * New York belvárosában történt robbantássorozat nyomozása, műsorvezető John McClain nyomozó
*/
Python példa
Forráskód
Pythonban
kezelők = []
def car_handler ( func ):
kezelők . append ( func )
return func
osztály Autó :
def __init__ ( self ):
self . név = Nincs
saját . km = 11100
self . üzemanyag = 5
saját . olaj = 5
@car_handler
def handle_fuel ( car ):
if car . üzemanyag < 10 :
nyomtatás ( "hozzáadott üzemanyag" )
autó . üzemanyag = 100
@car_handler
def handle_km ( car ):
if car . km > 10000 :
print ( "autótesztet csinált." )
autó . km = 0
@car_handler
def handle_oil ( car ):
if car . olaj < 10 :
nyomat ( "Hozzáadott olaj" )
autó . olaj = 100
osztály Garázs :
def __init__ ( self , handlers = Nincs ):
self . kezelők = kezelők vagy []
def add_handler ( self , handler ):
self . kezelők . hozzáfűzés ( kezelő )
def handle_car ( self , car ) :
a kezelőnek önmagában . kezelők : felvezető ( autó )
if __name__ == '__main__' :
garage = Garázs ( kezelők )
autó = Autó ()
garázs . handle_car ( autó )
Linkek
Jegyzetek
- ↑ Felelősségi lánc a Delphiben