更新時間:2018年12月07日11時46分 來源:傳智播客 瀏覽次數(shù):
# 設計模式-責任鏈
## 定義
? 責任鏈模式(Chain of Responsibility)使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接受者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有對象處理完它為止。
? 責任:當接收者收到一個請求后就有責任要把這個請求處理完,如果它處理不了,則可以轉(zhuǎn)給其它處理者。
? 鏈:請求最終得到處理完成這個過程所經(jīng)歷過的每個處理者連接起來形成一條鏈。
類型:行為類模式
## 特點
1. 接收請求的對象連接成一條鏈,對象之間存在層級關(guān)系。
2. 這些對象可處理請求,也可傳遞請求,直到有對象處理該請求
## 責任鏈模式涉及到的角色
1. 抽象處理者角色(Handler):定義了處理請求的接口或者抽象類,提供了處理請求的方法(handlleRequest)和設置下一個處理者(nextHandler)的方法
2. 具體處理者角色(ConcreteHandler):實現(xiàn)或者繼承抽象這角色,具體邏輯根據(jù)實際的架構(gòu)來定
## 責任鏈模式類圖
![class](pics\class.png)
## 實例:員工晉級流程處理
### 分析
? 員工晉級流程涉及多個部門的審批。我們可以用UML的活動圖來表示
![員工晉升流程圖](pics\員工晉升流程圖.png)
責任鏈模式是一種行為模式,因此我們可以給上圖中UML圖中所涉及到的每個處理行為都定義成一個真正的處理類
### 代碼實現(xiàn)
#### 1. 項目目錄結(jié)構(gòu)
![工程目錄結(jié)構(gòu)](pics\工程目錄結(jié)構(gòu).png)
#### 2. 創(chuàng)建抽象處理者角色
Hanlder類
```java
package com.itheima.demo.handler;
public abstract class Handler {
// 下個處理器
private Handler nextHandler;
// 處理當下的請求
public abstract void handleRequest();
// 獲取下個處理器
public Handler getNextHandler() {
return nextHandler;
}
// 設置下個處理器
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
}
```
#### 3. 創(chuàng)建各個具體處理者角色
* 員工發(fā)起晉級申請?zhí)幚?/p>
```java
package com.itheima.demo.handler;
/**
* 員工晉升申請
*
*/
public class EmpRequestPromotionHandler extends Handler {
/**
* 處理提交晉升申請
*/
@Override
public void handleRequest() {
System.out.println("員工提交晉升申請");
// 由下個處理者來處理
getNextHandler().handleRequest();
}
}
```
* 直屬領(lǐng)導的處理
```java
package com.itheima.demo.handler;
/**
* 直屬領(lǐng)導的處理
*
*/
public class Level1Handler extends Handler {
/**
* 直屬領(lǐng)導的處理: 填寫晉升人員基本情況
*/
@Override
public void handleRequest() {
System.out.println("--直屬領(lǐng)導的處理: 填寫晉升人員基本情況");
// 處理完后由下個處理者處理
getNextHandler().handleRequest();
}
}
```
* 部門總監(jiān)的處理
```java
package com.itheima.demo.handler;
/**
* 部門總監(jiān)的處理
*
*/
public class Level2Handler extends Handler {
/**
* 部門總監(jiān)的處理: 填寫晉升人員基本情況
*/
@Override
public void handleRequest() {
System.out.println("----部門總監(jiān)的處理: 進入能力業(yè)績考核");
int random = (int)(Math.random() * 10);
if(random < 9) {
System.out.println("----考核通過");
// 交給下個處理者處理
getNextHandler().handleRequest();
}else {
System.out.println("----考核沒通過");
System.out.println("流程結(jié)束");
}
}
}
```
* 執(zhí)行總裁的處理
```java
package com.itheima.demo.handler;
/**
* 執(zhí)行總裁的處理
*
*/
public class Level3Handler extends Handler {
/**
* 根據(jù)組織架構(gòu)判定是否晉升
*/
@Override
public void handleRequest() {
System.out.println("------執(zhí)行總裁的處理:根據(jù)組織架構(gòu)判定是否晉升");
int random = (int)(Math.random() * 10);
if(random < 9) {
System.out.println("------審批通過");
// 考核通過,交給下個處理者處理
getNextHandler().handleRequest();
}else {
System.out.println("------審批沒通過");
System.out.println("流程結(jié)束");
}
}
}
```
* 人事部的處理
```java
package com.itheima.demo.handler;
/**
* 人事部的處理
*/
public class HR1Handler extends Handler {
/**
* 是否符合晉升標準
*/
@Override
public void handleRequest() {
System.out.println("--------人事部的處理: 是否符合晉升標準");
int random = (int)(Math.random() * 10);
if(random < 9) {
System.out.println("--------審批通過");
// 考核通過,交給下個處理者處理
getNextHandler().handleRequest();
}else {
System.out.println("--------審批沒通過");
System.out.println("流程結(jié)束");
}
}
}
```
* 人事總裁的處理
```java
package com.itheima.demo.handler;
/**
* 人事總裁的處理
*/
public class HR2Handler extends Handler {
/**
* 是否符合晉升標準審批
*/
@Override
public void handleRequest() {
System.out.println("----------人事總裁的處理: 是否符合晉升標準審批");
int random = (int)(Math.random() * 10);
if(random < 9) {
System.out.println("----------審批通過");
// 考核通過,交給下個處理者處理
getNextHandler().handleRequest();
}else {
System.out.println("----------審批沒通過");
System.out.println("流程結(jié)束");
}
}
}
```
* 人事部通知處理
```java
package com.itheima.demo.handler;
/**
* 人事部的處理2
*/
public class HRAdviceHandler extends Handler {
/**
* 通知晉升處理
*/
@Override
public void handleRequest() {
System.out.println("--------------人事部的處理2:通知晉升人員確認");
// 處理完后由下個處理者處理
getNextHandler().handleRequest();
}
}
```
* 員工簽名的處理
```java
package com.itheima.demo.handler;
/**
* 員工簽名的處理
*/
public class EmpSignUpHandler extends Handler {
/**
* 員工簽名的處理
*/
@Override
public void handleRequest() {
System.out.println("----------------員工的處理2:簽字確認");
// 處理完后由下個處理者處理
getNextHandler().handleRequest();
}
}
```
* 人事部通告與歸檔的處理
```java
package com.itheima.demo.handler;
/**
* 人事部通告與歸檔的處理
*/
public class HRAnnouncementHandler extends Handler {
/**
* 通告與歸檔
*/
@Override
public void handleRequest() {
System.out.println("------------------人事部的處理3:通告與歸檔");
System.out.println("全部流程走完");
}
}
```
#### 4. 創(chuàng)建調(diào)用類
```java
package com.itheima.demo;
import com.itheima.demo.handler.EmpRequestPromotionHandler;
import com.itheima.demo.handler.EmpSignUpHandler;
import com.itheima.demo.handler.HR1Handler;
import com.itheima.demo.handler.HR2Handler;
import com.itheima.demo.handler.HRAdviceHandler;
import com.itheima.demo.handler.HRAnnouncementHandler;
import com.itheima.demo.handler.Handler;
import com.itheima.demo.handler.Level1Handler;
import com.itheima.demo.handler.Level2Handler;
import com.itheima.demo.handler.Level3Handler;
public class Client {
public static void main(String[] args) {
// 構(gòu)建每個行為的處理器
Handler empHandler = new EmpRequestPromotionHandler();
Handler level1Handler = new Level1Handler();
Handler level2Handler = new Level2Handler();
Handler level3Handler = new Level3Handler();
Handler hr1Handler = new HR1Handler();
Handler hr2Handler = new HR2Handler();
Handler hrAdviceHandler = new HRAdviceHandler();
Handler empSignUpHandler = new EmpSignUpHandler();
Handler hrAnnouncementHandler = new HRAnnouncementHandler();
// 設置每個處理的下個處理器
empHandler.setNextHandler(level1Handler);
level1Handler.setNextHandler(level2Handler);
level2Handler.setNextHandler(level3Handler);
level3Handler.setNextHandler(hr1Handler);
hr1Handler.setNextHandler(hr2Handler);
hr2Handler.setNextHandler(hrAdviceHandler);
hrAdviceHandler.setNextHandler(empSignUpHandler);
empSignUpHandler.setNextHandler(hrAnnouncementHandler);
// 員工發(fā)起晉級申請
empHandler.handleRequest();
}
}
```
#### 5. 運行效果
![result](pics\result.png)
## 總結(jié)
? 責任鏈模式通過建立一條鏈來組織請求的處理者,請求將沿著鏈進行傳遞,而請求發(fā)送者無須知道請求在何時、何處以及如何被處理,實現(xiàn)了請求發(fā)送者與處理者的解耦。在實際軟件開發(fā)中,如果遇到有多個對象可以處理同一請求時可以考慮使用職責鏈模式,一般都可以用來保證請求得到最終的執(zhí)行。