請求的鏈式處理 職責鏈模式(二)

2021-08-10 22:05:30 字數 1749 閱讀 8963

很多情況下,在乙個軟體系統中可以處理某個請求的物件不止乙個,例如

scm系統中的採購單審批,主任、副董事長、董事長和董事會都可以處理採購單,他們可以構成一條處理採購單的鏈式結構,採購單沿著這條鏈進行傳遞,這條鏈就稱為職責鏈。職責鏈可以是一條直線、乙個環或者乙個樹形結構,最常見的職責鏈是直線型,即沿著一條單向的鏈來傳遞請求。鏈上的每乙個物件都是請求處理者,職責鏈模式可以將請求的處理者組織成一條鏈,並讓請求沿著鏈傳遞,由鏈上的處理者對請求進行相應的處理,客戶端無須關心請求的處理細節以及請求的傳遞,只需將請求傳送到鏈上即可,實現請求傳送者和請求處理者解耦。

職責鏈模式定義如下:

職責鏈模式(chain of responsibility  pattern):避免請求傳送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈,並且沿著這條鏈傳遞請求,直到有物件處理它為止。職責鏈模式是一種物件行為型模式。

職責鏈模式結構的核心在於引入了乙個抽象處理者。職責鏈模式結構如圖16-2所示:

在職責鏈模式結構圖中包含如下幾個角色:

●handler

(抽象處理者):它定義了乙個處理請求的介面,一般設計為抽象類,由於不同的具體處理者處理請求的方式不同,因此在其中定義了抽象請求處理方法。因為每乙個處理者的下家還是乙個處理者,因此在抽象處理者中定義了乙個抽象處理者型別的物件(如結構圖中的successor),作為其對下家的引用。通過該引用,處理者可以連成一條鏈。

●concretehandler(具體處理者):它是抽象處理者的子類,可以處理使用者請求,在具體處理者類中實現了抽象處理者中定義的抽象請求處理方法,在處理請求之前需要進行判斷,看是否有相應的處理許可權,如果可以處理請求就處理它,否則將請求**給後繼者;在具體處理者中可以訪問鏈中下乙個物件,以便請求的**。

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

職責鏈模式的核心在於抽象處理者類的設計,抽象處理者的典型**如下所示:

abstract class handler   

public abstract void handlerequest(string request);

}

上述**中,抽象處理者類定義了對下家的引用物件,以便將請求**給下家,該物件的訪問符可設為protected,在其子類中可以使用。在抽象處理者類中宣告了抽象的請求處理方法,具體實現交由子類完成。

具體處理者是抽象處理者的子類,它具有兩大作用:第一是處理請求,不同的具體處理者以不同的形式實現抽象請求處理方法handlerequest();第二是**請求,如果該請求超出了當前處理者類的許可權,可以將該請求**給下家。具體處理者類的典型**如下:

class concretehandler extends handler   

else

} }

在具體處理類中通過對請求進行判斷可以做出相應的處理。

需要注意的是,職責鏈模式並不建立職責鏈,職責鏈的建立工作必須由系統的其他部分來完成,一般是在使用該職責鏈的客戶端中建立職責鏈

。職責鏈模式降低了請求的傳送端和接收端之間的耦合,使多個物件都有機會處理這個請求。 

思考如何在客戶端建立一條職責鏈?

請求的鏈式處理 職責鏈模式(三)

為了讓採購單的審批流程更加靈活,並實現採購單的鏈式傳遞和處理,sunny公司開發人員使用職責鏈模式來實現採購單的分級審批,其基本結構如圖16 3所示 採購單 請求類 class purchaserequest public void setamount double amount public do...

請求的鏈式處理 職責鏈模式(一)

一對二 過 過 這聲音熟悉嗎?你會想到什麼?對!紙牌。在類似 鬥地主 這樣的紙牌遊戲中,某人出牌給他的下家,下家看看手中的牌,如果要不起上家的牌則將出牌請求再 給他的下家,其下家再進行判斷。乙個迴圈下來,如果其他人都要不起該牌,則最初的出牌者可以打出新的牌。在這個過程中,牌作為乙個請求沿著一條鏈在傳...

請求的鏈式處理 職責鏈模式(一)

一對二 過 過 這聲音熟悉嗎?你會想到什麼?對!紙牌。在類似 鬥地主 這樣的紙牌遊戲中,某人出牌給他的下家,下家看看手中的牌,如果要不起上家的牌則將出牌請求再 給他的下家,其下家再進行判斷。乙個迴圈下來,如果其他人都要不起該牌,則最初的出牌者可以打出新的牌。在這個過程中,牌作為乙個請求沿著一條鏈在傳...