C 設計模式 21 責任鏈模式

2021-12-29 21:03:43 字數 2835 閱讀 3370

一、引言

在現實生活中,有很多請求並不是乙個人說了就算的,例如面試時的工資,低於1萬的薪水可能技術經理就可以決定了,但是1萬~1萬5的薪水可能技術經理就沒這個權利批准,可能就需要請求技術總監的批准,所以在面試的完後,經常會有面試官說,你這個薪水我這邊覺得你這技術可以拿這個薪水的,但是還需要技術總監的批准等的話。這個例子也就詮釋了本文要介紹的內容。生活中的這個例子真是應用了責任鏈模式。

二、責任鏈模式介紹

2.1 責任鏈模式的定義

從生活中的例子可以發現,某個請求可能需要幾個人的審批,即使技術經理審批完了,還需要上一級的審批。這樣的例子,還有公司中的請假,少於3天的,直屬leader就可以批准,3天到7天之內就需要專案經理批准,多餘7天的就需要技術總監的批准了。介紹了這麼多生活中責任鏈模式的例子的,下面具體給出物件導向中責任鏈模式的定義。

責任鏈模式指的是——某個請求需要多個物件進行處理,從而避免請求的傳送者和接收之間的耦合關係。將這些物件連成一條鍊子,並沿著這條鍊子傳遞該請求,直到有物件處理它為止。

2.2 責任鏈模式的結構圖

從責任鏈模式的定義可以發現,責任鏈模式涉及的物件只有處理者角色,但由於有多個處理者,它們具有共同的處理請求的方法,所以這裡抽象出乙個抽象處理者角色進行**復用。這樣分析下來,責任鏈模式的結構圖也就不言而喻了,具體結構圖如下所示。  

主要涉及兩個角色:

抽象處理者角色(handler):定義出乙個處理請求的介面。這個介面通常由介面或抽象類來實現。

具體處理者角色(concretehandler):具體處理者接受到請求後,可以選擇將該請求處理掉,或者將請求傳給下乙個處理者。因此,每個具體處理者需要儲存下乙個處理者的引用,以便把請求傳遞下去。

2.3 責任鏈模式的實現

有了上面的介紹,下面以公司採購東西為例子來實現責任鏈模式。公司規定,採購架構總價在1萬之內,經理級別的人批准即可,總價大於1萬小於2萬5的則還需要副總進行批准,總價大於2萬5小於10萬的需要還需要總經理批准,而大於總價大於10萬的則需要組織乙個會議進行討論。對於這樣乙個需求,最直觀的方法就是設計乙個方法,引數是採購的總價,然後在這個方法內對**進行調整判斷,然後針對不同的條件交給不同級別的人去處理,這樣確實可以解決問題,但這樣一來,我們就需要多重if-else語句來進行判斷,但當加入乙個新的條件範圍時,我們又不得不去修改原來設計的方法來再新增乙個條件判斷,這樣的設計顯然違背了「開-閉」原則。這時候,可以採用責任鏈模式來解決這樣的問題。具體實現**如下所示。

複製**

namespace chainofresponsibility

// 產品名字

public string productname

public purchaserequest(double amount, string productname)

}// 審批人,handler

public abstract class approver

public string name

public approver(string name)

public abstract void processrequest(purchaserequest request);

}// concretehandler

public class manager : approver

public override void processrequest(purchaserequest request)

- approved the request of purshing ", this, name, request.productname);

}else if (nextapprover != null)}}

// concretehandler,副總

public class vicepresident : approver

public override void processrequest(purchaserequest request)

- approved the request of purshing ", this, name, request.productname);

}else if (nextapprover != null)}}

// concretehandler,總經理

public class president :approver

public override void processrequest(purchaserequest request)

- approved the request of purshing ", this, name, request.productname);

}else}}

class program

}}複製**

既然,原來的設計會因為**條件範圍的變化而導致不利於擴充套件,根據「封裝變化」的原則,此時我們想的自然是能不能把**範圍細化到不同的類中呢?因為每個**範圍都決定某個批准者,這裡就聯想到建立多個批准類,這樣每個類中只需要針對他自己這個範圍的**判斷。這樣也就是責任鏈的最後實現方式了,具體的執行結果如下圖所示。  

三、責任鏈模式的應用場景 

在以下場景中可以考慮使用責任鏈模式:

乙個系統的審批需要多個物件才能完成處理的情況下,例如請假系統等。

**中存在多個if-else語句的情況下,此時可以考慮使用責任鏈模式來對**進行重構。

四、責任鏈模式的優缺點

責任鏈模式的優點不言而喻,主要有以下點:

降低了請求的傳送者和接收者之間的耦合。

把多個條件判定分散到各個處理類中,使得**更加清晰,責任更加明確。

責任鏈模式也具有一定的缺點,如:

在找到正確的處理物件之前,所有的條件判定都要執行一遍,當責任鏈過長時,可能會引起效能的問題

可能導致某個請求不被處理。

C 設計模式 21 責任鏈模式

原文 c 設計模式 21 責任鏈模式 在現實生活中,有很多請求並不是乙個人說了就算的,例如面試時的工資,低於1萬的薪水可能技術經理就可以決定了,但是1萬 1萬5的薪水可能技術經理就沒這個權利批准,可能就需要請求技術總監的批准,所以在面試的完後,經常會有面試官說,你這個薪水我這邊覺得你這技術可以拿這個...

C 設計模式 21 責任鏈模式

在現實生活中,有很多請求並不是乙個人說了就算的,例如面試時的工資,低於1萬的薪水可能技術經理就可以決定了,但是1萬 1萬5的薪水可能技術經理就沒這個權利批准,可能就需要請求技術總監的批准,所以在面試的完後,經常會有面試官說,你這個薪水我這邊覺得你這技術可以拿這個薪水的,但是還需要技術總監的批准等的話...

C 設計模式 責任鏈模式

優點 請求和處理分開 缺點 避免出現超長鏈的情況,一般的做法是在handler中設定乙個最大節點數量,在setnext方法中判斷是否已經是超過其閾值,超過則不允許該鏈建立,避免無意識地破壞系統效能 抽象處理者 ifndef handler h define handler h include req...