更新时间:2018年12月07日11时46分 来源:传智播客 浏览次数:
# 设计模式-责任链
## 定义
责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理完它为止。
责任:当接收者收到一个请求后就有责任要把这个请求处理完,如果它处理不了,则可以转给其它处理者。
链:请求最终得到处理完成这个过程所经历过的每个处理者连接起来形成一条链。
类型:行为类模式
## 特点
1. 接收请求的对象连接成一条链,对象之间存在层级关系。
2. 这些对象可处理请求,也可传递请求,直到有对象处理该请求
## 责任链模式涉及到的角色
1. 抽象处理者角色(Handler):定义了处理请求的接口或者抽象类,提供了处理请求的方法(handlleRequest)和设置下一个处理者(nextHandler)的方法
2. 具体处理者角色(ConcreteHandler):实现或者继承抽象这角色,具体逻辑根据实际的架构来定
## 责任链模式类图
![class](pics\class.png)
## 实例:员工晋级流程处理
### 分析
员工晋级流程涉及多个部门的审批。我们可以用UML的活动图来表示
![员工晋升流程图](pics\员工晋升流程图.png)
责任链模式是一种行为模式,因此我们可以给上图中UML图中所涉及到的每个处理行为都定义成一个真正的处理类
### 代码实现
#### 1. 项目目录结构
![工程目录结构](pics\工程目录结构.png)
#### 2. 创建抽象处理者角色
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. 创建各个具体处理者角色
* 员工发起晋级申请处理
```java
package com.itheima.demo.handler;
/**
* 员工晋升申请
*
*/
public class EmpRequestPromotionHandler extends Handler {
/**
* 处理提交晋升申请
*/
@Override
public void handleRequest() {
System.out.println("员工提交晋升申请");
// 由下个处理者来处理
getNextHandler().handleRequest();
}
}
```
* 直属领导的处理
```java
package com.itheima.demo.handler;
/**
* 直属领导的处理
*
*/
public class Level1Handler extends Handler {
/**
* 直属领导的处理: 填写晋升人员基本情况
*/
@Override
public void handleRequest() {
System.out.println("--直属领导的处理: 填写晋升人员基本情况");
// 处理完后由下个处理者处理
getNextHandler().handleRequest();
}
}
```
* 部门总监的处理
```java
package com.itheima.demo.handler;
/**
* 部门总监的处理
*
*/
public class Level2Handler 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("流程结束");
}
}
}
```
* 执行总裁的处理
```java
package com.itheima.demo.handler;
/**
* 执行总裁的处理
*
*/
public class Level3Handler 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("流程结束");
}
}
}
```
* 人事部的处理
```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("流程结束");
}
}
}
```
* 人事总裁的处理
```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("流程结束");
}
}
}
```
* 人事部通知处理
```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. 创建调用类
```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) {
// 构建每个行为的处理器
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);
// 员工发起晋级申请
empHandler.handleRequest();
}
}
```
#### 5. 运行效果
![result](pics\result.png)
## 总结
责任链模式通过建立一条链来组织请求的处理者,请求将沿着链进行传递,而请求发送者无须知道请求在何时、何处以及如何被处理,实现了请求发送者与处理者的解耦。在实际软件开发中,如果遇到有多个对象可以处理同一请求时可以考虑使用职责链模式,一般都可以用来保证请求得到最终的执行。