定義:使用多個類而不是一個去傳遞請求,可以很大程度上降低請求的發出者與接受者之間的耦合。多個類成鍊式,去接受請求,在請求的接受者接受之前傳遞請求。
uml圖:
類:
handler: 定義處理請求的接口
concretehandler:1:處理請求
2:擷取下一個連結者
3:如果這個類可以處理請求,處理;否則傳遞給下一個連結者。
client: 初始化請求,發送請求。
用c#寫的小例子:
using system;
namespace dofactory.gangoffour.chain.structural
{
/// <summary>
/// 責任鍊設計模式
/// </summary>
class mainapp
/// 程式入口點
static void main()
// 建立責任鍊
handler h1 = new concretehandler1();
handler h2 = new concretehandler2();
handler h3 = new concretehandler3();
h1.setsuccessor(h2);
h2.setsuccessor(h3);
// 初始化請求
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
foreach (int request in requests)
h1.handlerequest(request);
}
// 等待
console.readkey();
/// 'handler'接口或抽象類
abstract class handler
protected handler successor;
public void setsuccessor(handler successor)
this.successor = successor;
public abstract void handlerequest(int request);
///'concretehandler1' 類
class concretehandler1 : handler
public override void handlerequest(int request)
if (request >= 0 && request < 10)
console.writeline("{0} handled request {1}",
this.gettype().name, request);
else if (successor != null)
successor.handlerequest(request);
/// the 'concretehandler2' class
class concretehandler2 : handler
if (request >= 10 && request < 20)
/// the 'concretehandler3' class
class concretehandler3 : handler
if (request >= 20 && request < 30)
現實點的例子
namespace dofactory.gangoffour.chain.realworld
/// mainapp startup class for real-world
/// chain of responsibility design pattern.
/// entry point into console application.
// setup chain of responsibility
approver larry = new director();
approver sam = new vicepresident();
approver tammy = new president();
larry.setsuccessor(sam);
sam.setsuccessor(tammy);
// generate and process purchase requests
purchase p = new purchase(2034, 350.00, "assets");
larry.processrequest(p);
p = new purchase(2035, 32590.10, "project x");
p = new purchase(2036, 122100.00, "project y");
// wait for user
/// the 'handler' abstract class
abstract class approver
protected approver successor;
public void setsuccessor(approver successor)
public abstract void processrequest(purchase purchase);
/// the 'concretehandler' class
class director : approver
public override void processrequest(purchase purchase)
if (purchase.amount < 10000.0)
console.writeline("{0} approved request# {1}",
this.gettype().name, purchase.number);
successor.processrequest(purchase);
class vicepresident : approver
if (purchase.amount < 25000.0)
class president : approver
if (purchase.amount < 100000.0)
else
console.writeline(
"request# {0} requires an executive meeting!",
purchase.number);
/// class holding request details
class purchase
private int _number;
private double _amount;
private string _purpose;
// constructor
public purchase(int number, double amount, string purpose)
this._number = number;
this._amount = amount;
this._purpose = purpose;
// gets or sets purchase number
public int number
get { return _number; }
set { _number = value; }
// gets or sets purchase amount
public double amount
get { return _amount; }
set { _amount = value; }
// gets or sets purchase purpose
public string purpose
get { return _purpose; }
set { _purpose = value; }