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

2021-09-19 11:35:56 字數 3601 閱讀 4386

「一對二」,「過」,「過」……這聲音熟悉嗎?你會想到什麼?對!紙牌。在類似「鬥地主」這樣的紙牌遊戲中,某人出牌給他的下家,下家看看手中的牌,如果要不起上家的牌則將出牌請求再**給他的下家,其下家再進行判斷。乙個迴圈下來,如果其他人都要不起該牌,則最初的出牌者可以打出新的牌。在這個過程中,牌作為乙個請求沿著一條鏈在傳遞,每一位紙牌的玩家都可以處理該請求。在設計模式中,我們也有一種專門用於處理這種請求鏈式傳遞的模式,它就是本章將要介紹的職責鏈模式。

sunny軟體公司承接了某企業scm(supply chain management,**鏈管理)系統的開發任務,其中包含乙個採購審批子系統。該企業的採購審批是分級進行的,即根據採購金額的不同由不同層次的主管人員來審批,主任可以審批5萬元以下(不包括5萬元)的採購單,副董事長可以審批5萬元至10萬元(不包括10萬元)的採購單,董事長可以審批10萬元至50萬元(不包括50萬元)的採購單,50萬元及以上的採購單就需要開董事會討論決定。如圖16-1所示:

圖16-1 採購單分級審批示意圖

如何在軟體中實現採購單的分級審批?sunny軟體公司開發人員提出了乙個初始解決方案,在系統中提供乙個採購單處理類purchaserequesthandler用於統一處理採購單,其框架**如下所示:

//採購單處理類

class

purchaserequesthandler

else

if (request.getamount() < 100000)   else

if (request.getamount() < 500000)   else  }  //主任審批採購單

public

void

handlebydirector

(purchaserequest request)

//副董事長審批採購單

public

void

handlebyvicepresident

(purchaserequest request)

//董事長審批採購單

public

void

handlebypresident

(purchaserequest request)

//董事會審批採購單

public

void

handlebycongress

(purchaserequest request)

}

問題貌似很簡單,但仔細分析,發現上述方案存在如下幾個問題:

(1)purchaserequesthandler類較為龐大,各個級別的審批方法都集中在乙個類中,違反了「單一職責原則」,測試和維護難度大。

(2)如果需要增加乙個新的審批級別或調整任何一級的審批金額和審批細節(例如將董事長的審批額度改為60萬元)時都必須修改源**並進行嚴格測試,此外,如果需要移除某一級別(例如金額為10萬元及以上的採購單直接由董事長審批,不再設副董事長一職)時也必須對源**進行修改,違反了「開閉原則」。

(3)審批流程的設定缺乏靈活性,現在的審批流程是「主任-->副董事長-->董事長-->董事會」,如果需要改為「主任-->董事長-->董事會」,在此方案中只能通過修改源**來實現,客戶端無法定製審批流程。

如何針對上述問題對系統進行改進?sunny公司開發人員迫切需要一種新的設計方案,還好有職責鏈模式,通過使用職責鏈模式我們可以最大程度地解決這些問題,下面讓我們正式進入職責鏈模式的學習。

「一對二」,「過」,「過」……這聲音熟悉嗎?你會想到什麼?對!紙牌。在類似「鬥地主」這樣的紙牌遊戲中,某人出牌給他的下家,下家看看手中的牌,如果要不起上家的牌則將出牌請求再**給他的下家,其下家再進行判斷。乙個迴圈下來,如果其他人都要不起該牌,則最初的出牌者可以打出新的牌。在這個過程中,牌作為乙個請求沿著一條鏈在傳遞,每一位紙牌的玩家都可以處理該請求。在設計模式中,我們也有一種專門用於處理這種請求鏈式傳遞的模式,它就是本章將要介紹的職責鏈模式。

sunny軟體公司承接了某企業scm(supply chain management,**鏈管理)系統的開發任務,其中包含乙個採購審批子系統。該企業的採購審批是分級進行的,即根據採購金額的不同由不同層次的主管人員來審批,主任可以審批5萬元以下(不包括5萬元)的採購單,副董事長可以審批5萬元至10萬元(不包括10萬元)的採購單,董事長可以審批10萬元至50萬元(不包括50萬元)的採購單,50萬元及以上的採購單就需要開董事會討論決定。如圖16-1所示:

圖16-1 採購單分級審批示意圖

如何在軟體中實現採購單的分級審批?sunny軟體公司開發人員提出了乙個初始解決方案,在系統中提供乙個採購單處理類purchaserequesthandler用於統一處理採購單,其框架**如下所示:

//採購單處理類

class

purchaserequesthandler

else

if (request.getamount() < 100000)   else

if (request.getamount() < 500000)   else  }  //主任審批採購單

public

void

handlebydirector

(purchaserequest request)

//副董事長審批採購單

public

void

handlebyvicepresident

(purchaserequest request)

//董事長審批採購單

public

void

handlebypresident

(purchaserequest request)

//董事會審批採購單

public

void

handlebycongress

(purchaserequest request)

}

問題貌似很簡單,但仔細分析,發現上述方案存在如下幾個問題:

(1)purchaserequesthandler類較為龐大,各個級別的審批方法都集中在乙個類中,違反了「單一職責原則」,測試和維護難度大。

(2)如果需要增加乙個新的審批級別或調整任何一級的審批金額和審批細節(例如將董事長的審批額度改為60萬元)時都必須修改源**並進行嚴格測試,此外,如果需要移除某一級別(例如金額為10萬元及以上的採購單直接由董事長審批,不再設副董事長一職)時也必須對源**進行修改,違反了「開閉原則」。

(3)審批流程的設定缺乏靈活性,現在的審批流程是「主任-->副董事長-->董事長-->董事會」,如果需要改為「主任-->董事長-->董事會」,在此方案中只能通過修改源**來實現,客戶端無法定製審批流程。

如何針對上述問題對系統進行改進?sunny公司開發人員迫切需要一種新的設計方案,還好有職責鏈模式,通過使用職責鏈模式我們可以最大程度地解決這些問題,下面讓我們正式進入職責鏈模式的學習。

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

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

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

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

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

很多情況下,在乙個軟體系統中可以處理某個請求的物件不止乙個,例如 scm系統中的採購單審批,主任 副董事長 董事長和董事會都可以處理採購單,他們可以構成一條處理採購單的鏈式結構,採購單沿著這條鏈進行傳遞,這條鏈就稱為職責鏈。職責鏈可以是一條直線 乙個環或者乙個樹形結構,最常見的職責鏈是直線型,即沿著...