天天看點

設計模式之責任鍊模式

定義:使用多個類而不是一個去傳遞請求,可以很大程度上降低請求的發出者與接受者之間的耦合。多個類成鍊式,去接受請求,在請求的接受者接受之前傳遞請求。

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; }