责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦,请求沿着责任链传递,直到有一个对象处理了它为止。
责任链上的处理者负责处理请求,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递,所以责任链将请求的发送者和请求的处理者解耦了。
一般来说,责任链模式由三类构成:
- 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
- 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
=========================================================================
我们来模拟一个三级处理,每一个权限用户只能处理他自己权限对应的员工,在责任链上进行处理
首先定义一个抽象处理者:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName Approve.java
* @Description 决策者抽象类
* @createTime 2022年03月15日 15:45:00
*/
public abstract class Approve {
/**
* 下一个链
*/
Approve nextLevel;
/**
* 姓名
*/
String name;
public Approve(String name)
{
this.name=name;
}
/**
* 权限处理
* @param authUser 权限用户
*/
public abstract void processAuth(AuthUser authUser);
/**
* 设置下一个决策节点
* @param nextLevel 下一个决策节点
*/
public Approve setNextLevel(Approve nextLevel) {
this.nextLevel=nextLevel;
return this;
}
}
抽象处理者包含了权限处理的抽象方法,由实现类分别复写。
抽出常量类,划分权限:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName Common.java
* @Description 常量类
* @createTime 2022年03月16日 10:39:00
*/
public class Common {
public static class Level{
public static final String LEVEL_ONE = "level1";
public static final String LEVEL_TWO = "level2";
public static final String LEVEL_THREE = "level3";
}
}
权限用户类,对权限用户封装:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName AuthUser.java
* @Description 权限用户类
* @createTime 2022年03月16日 10:48:00
*/
public class AuthUser {
private String userid;
private String auth;
public AuthUser(String userid,String auth){
this.userid=userid;
this.auth=auth;
}
public String getAuth() {
return auth;
}
public String getUserid() {
return userid;
}
}
分别实现三级验证:
第一级:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName LevelOne.java
* @Description 第一级验证
* @createTime 2022年03月15日 17:07:00
*/
public class LevelOne extends Approve{
public LevelOne(String name) {
super(name);
}
@Override
public void processAuth(AuthUser authUser) {
String uid = authUser.getUserid();
String auth = authUser.getAuth();
if (Common.Level.LEVEL_ONE.equals(auth)){
System.out.println("通过验证");
System.out.println(" 用户名:"+name+" 处理人id: "+uid);
}else {
System.out.println("用户:"+uid+" 没有权限处理"+name);
nextLevel.processAuth(authUser);
}
}
}
第二级:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName LevelTwo.java
* @Description 第二级验证
* @createTime 2022年03月15日 17:12:00
*/
public class LevelTwo extends Approve{
public LevelTwo(String name) {
super(name);
}
@Override
public void processAuth(AuthUser authUser) {
String uid = authUser.getUserid();
String auth = authUser.getAuth();
if (Common.Level.LEVEL_TWO.equals(auth)){
System.out.println("通过验证");
System.out.println(" 用户名:"+name+" 处理人id: "+uid);
}else {
System.out.println("用户:"+uid+" 没有权限处理"+name);
nextLevel.processAuth(authUser);
}
}
}
第三级:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName LevelThree.java
* @Description 第三级验证
* @createTime 2022年03月15日 17:17:00
*/
public class LevelThree extends Approve{
public LevelThree(String name) {
super(name);
}
@Override
public void processAuth(AuthUser authUser) {
String uid = authUser.getUserid();
String auth = authUser.getAuth();
if (Common.Level.LEVEL_THREE.equals(auth)){
System.out.println("通过验证");
System.out.println("用户名:"+name+" 处理人id: "+uid);
}else {
System.out.println("用户:"+uid+" 没有权限处理"+name);
nextLevel.processAuth(authUser);
}
}
}
测试一下:
package ChainOfResponsibilityPattern;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName ChainTest.java
* @Description 责任链模式测试类
* @createTime 2022年03月15日 17:18:00
*/
public class ChainTest {
public static void main(String[] args) {
Approve authChain = new LevelOne("张三").setNextLevel(new LevelTwo("李四").setNextLevel(new LevelThree("王五")));
AuthUser user1= new AuthUser("111",Common.Level.LEVEL_THREE);
AuthUser user2= new AuthUser("222",Common.Level.LEVEL_TWO);
AuthUser user3= new AuthUser("333",Common.Level.LEVEL_ONE);
authChain.processAuth(user1);
System.out.println("");
authChain.processAuth(user2);
System.out.println("");
authChain.processAuth(user3);
}
}
优点:
- 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
- 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
- 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
- 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
缺点:
- 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
- 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。