設計模式之責任鏈模式

2021-10-01 09:03:49 字數 1945 閱讀 6605

在現實生活中,常常會出現這樣的事例:乙個請求有多個物件可以處理,但每個物件的處理條件或許可權不同。例如,公司員工請假,可批假的領導有部門負責人、副總經理、總經理等,但每個領導能批准的天數不同,員工必須根據自己要請假的天數去找不同的領導簽名,也就是說員工必須記住每個領導的姓名、**和位址等資訊,這增加了難度。這樣的例子還有很多,如找領導出差報銷、生活中的「擊鼓傳花」遊戲等。

在計算機軟硬體中也有相關例子,如匯流排網中資料報傳送,每台計算機根據目標位址是否同自己的位址相同來決定是否接收;還有異常處理中,處理程式根據異常的型別決定自己是否處理該異常;還有 struts2 的***、jsp 和 servlet 的 filter 等,所有這些,如果用責任鏈模式都能很好解決。

責任鏈(chain of responsibility)模式的定義:為了避免請求傳送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一物件記住其下乙個物件的引用而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有物件處理它為止。

注意:責任鏈模式也叫職責鏈模式。

在責任鏈模式中,客戶只需要將請求傳送到責任鏈上即可,無須關心請求的處理細節和請求的傳遞過程,所以責任鏈將請求的傳送者和請求的處理者解耦了。

責任鏈模式是一種物件行為型模式,其主要優點如下。

降低了物件之間的耦合度。該模式使得乙個物件無須知道到底是哪乙個物件處理其請求以及鏈的結構,傳送者和接收者也無須擁有對方的明確資訊。

增強了系統的可擴充套件性。可以根據需要增加新的請求處理類,滿足開閉原則。

增強了給物件指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。

責任鏈簡化了物件之間的連線。每個物件只需保持乙個指向其後繼者的引用,不需保持其他所有處理者的引用,這避免了使用眾多的 if 或者 if···else 語句。

責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下乙個物件完成,明確各類的責任範圍,符合類的單一職責原則。

其主要缺點如下。

不能保證每個請求一定被處理。由於乙個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。

對比較長的職責鏈,請求的處理可能涉及多個處理物件,系統效能將受到一定影響。

職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的複雜性,可能會由於職責鏈的錯誤設定而導致系統出錯,如可能會造成迴圈呼叫。

通常情況下,可以通過資料鏈表來實現職責鏈模式的資料結構。

職責鏈模式主要包含以下角色。

抽象處理者(handler)角色:定義乙個處理請求的介面,包含抽象處理方法和乙個後繼連線。

具體處理者(concrete handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的後繼者。

客戶類(client)角色:建立處理鏈,並向鏈頭的具體處理者物件提交請求,它不關心處理細節和請求的傳遞過程。

package com.ywu.demo.designmode.chain;

/** * @description 責任鏈模式 在處理類中宣告下一級處理人

* @author wuya

* @date 2019/12/10

*/public

class

chainmodelmain

public handler setnexthandler

(handler nexthandler)

abstract

void

call()

;}class

handlera

extends

handler}}

class

handlerb

extends

handler}}

public

static

void

main

(string[

] args)

}

設計模式之 責任鏈模式

在一些情況下,對乙個訊息 含事件 的響應和處理需要很多物件來參與,這些物件對訊息的處理有前後順序,形成乙個處理鏈條,但物件是否真正處理訊息有賴於在它之前的物件的處理策略,前乙個物件處理後,後乙個物件則不需參與處理,這就是責任鏈模式。現實中有很多類似的場景,比如上訪,上訪一般是從最基層的信訪部門接受信...

設計模式之(責任鏈模式)

chain of responsibleity 責任鏈模式 在責任鏈模式 中,很多物件由每乙個物件對其下家的引用而接。起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某乙個物件決定處理此請求。客戶並不知道鏈上的哪乙個物件最終處理這個請求,系統可以在不影響客戶端的情況下動態的重新組織鏈和分配責任。處理者...

設計模式之責任鏈模式

假設現在乙個公司的請假流程如下 一天及以下由小組組長審批,一天以上三天以下由經理審批,三天以上七天以下由老闆審批,七天以上直接勸退。如果每次請假時都很長的if else 來判斷該去找誰請假,很不容易擴充套件,我們使用責任鏈模式來實現。首先,是乙個抽象的父類 public abstract class...