共计 4415 个字符,预计需要花费 12 分钟才能阅读完成。
写在后面
- 记录学习设计模式的笔记
- 进步对设计模式的灵活运用
学习地址
https://www.bilibili.com/vide…
https://www.bilibili.com/vide…
参考文章
http://c.biancheng.net/view/1…
我的项目源码
https://gitee.com/zhuang-kang/DesignPattern
27,责任链模式
27.1 责任链模式的定义和特点
责任链(Chain of Responsibility)模式的定义: 为了防止申请发送者与多个申请解决者耦合在一起,于是将所有申请的解决者通过前一对象记住其下一个对象的援用而连成一条链;当有申请产生时,可将申请沿着这条链传递,直到有对象解决它为止。
留神:责任链模式也叫职责链模式。
在责任链模式中,客户只须要将申请发送到责任链上即可,毋庸关怀申请的解决细节和申请的传递过程,申请会主动进行传递。所以责任链将申请的发送者和申请的解决者解耦了。
责任链模式是一种对象行为型模式,其次要长处如下。
- 升高了对象之间的耦合度。该模式使得一个对象毋庸晓得到底是哪一个对象解决其申请以及链的构造,发送者和接收者也毋庸领有对方的明确信息。
- 加强了零碎的可扩展性。能够依据须要减少新的申请解决类,满足开闭准则。
- 加强了给对象指派职责的灵活性。当工作流程发生变化,能够动静地扭转链内的成员或者调动它们的秩序,也可动静地新增或者删除责任。
- 责任链简化了对象之间的连贯。每个对象只需放弃一个指向其后继者的援用,不需放弃其余所有解决者的援用,这防止了应用泛滥的 if 或者 if···else 语句。
- 责任分担。每个类只须要解决本人该解决的工作,不该解决的传递给下一个对象实现,明确各类的责任范畴,合乎类的繁多职责准则。
其次要毛病如下。
- 不能保障每个申请肯定被解决。因为一个申请没有明确的接收者,所以不能保障它肯定会被解决,该申请可能始终传到链的末端都得不到解决。
- 对比拟长的职责链,申请的解决可能波及多个解决对象,零碎性能将受到肯定影响。
- 职责链建设的合理性要靠客户端来保障,减少了客户端的复杂性,可能会因为职责链的谬误设置而导致系统出错,如可能会造成循环调用。
27.2 责任链模式的构造与实现
27.2.1 责任链模式的构造
- 形象解决者(Handler)角色:定义一个解决申请的接口,蕴含形象解决办法和一个后继连贯。
- 具体解决者(Concrete Handler)角色:实现形象解决者的解决办法,判断是否解决本次申请,如果能够解决申请则解决,否则将该申请转给它的后继者。
- 客户类(Client)角色:创立解决链,并向链头的具体解决者对象提交申请,它不关怀解决细节和申请的传递过程。
27.2.1 代码实现
开发一个销假流程控制系统。销假一天以下的假只须要小组长批准即可;销假 1 天到 3 天的假还须要部门经理批准;申请 3 天到 7 天还须要总经理批准才行
关系类图
LeaveRequest
package com.zhuang.responsibility;
/**
* @Classname LeaveRequest
* @Description 请假条
* @Date 2021/3/31 16:21
* @Created by dell
*/
public class LeaveRequest {
// 姓名
private String name;
// 销假天数
private int num;
// 销假内容
private String content;
public LeaveRequest(String name, int num, String content) {
this.name = name;
this.num = num;
this.content = content;
}
public String getName() {return name;}
public int getNum() {return num;}
public String getContent() {return content;}
}
Handler
package com.zhuang.responsibility;
/**
* @Classname Handler
* @Description 用一句话形容类的作用
* @Date 2021/3/31 16:23
* @Created by dell
*/
public abstract class Handler {
protected final static int NUM_ONE = 1;
protected final static int NUM_THREE = 3;
protected final static int NUM_SEVEN = 7;
// 该领导解决的销假天数区间
private int numStart;
private int numEnd;
// 领导上还有领导
private Handler nextHandler;
// 设置销假天数范畴
public Handler(int numStart) {this.numStart = numStart;}
// 设置销假天数范畴
public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}
// 设置上级领导
public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}
// 提交请假条
public final void submit(LeaveRequest leaveRequest) {if (this.numStart == 0) {return;}
// 销假天数达到领导解决要求
if (leaveRequest.getNum() >= this.numStart) {this.handleLeave(leaveRequest);
// 如果还有下级 并且销假天数超过以后领导的解决范畴
if (this.nextHandler != null && leaveRequest.getNum() > numEnd) {
// 持续提交
this.nextHandler.submit(leaveRequest);
} else {System.out.println("流程完结!!!");
}
}
}
// 各级领导解决请假条办法
protected abstract void handleLeave(LeaveRequest leave);
}
GroupLeader
package com.zhuang.responsibility;
/**
* @Classname GroupLeader
* @Description 小组长类
* @Date 2021/3/31 16:33
* @Created by dell
*/
public class GroupLeader extends Handler {
//1- 3 天的假
public GroupLeader() {super(Handler.NUM_ONE, Handler.NUM_THREE);
}
@Override
protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "销假" + leave.getNum() + "天," + leave.getContent() + "!");
System.out.println("小组长审批通过:批准!");
}
}
Manager
package com.zhuang.responsibility;
/**
* @Classname Manager
* @Description 部门经理类
* @Date 2021/3/31 16:36
* @Created by dell
*/
public class Manager extends Handler {
//3- 7 天的假
public Manager() {super(Handler.NUM_THREE, Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "销假" + leave.getNum() + "天," + leave.getContent() + "!");
System.out.println("部门经理审批通过:批准!");
}
}
GeneralManager
package com.zhuang.responsibility;
/**
* @Classname GeneralManager
* @Description 总经理类
* @Date 2021/3/31 16:38
* @Created by dell
*/
public class GeneralManager extends Handler{
// 7 天以上的假
public GeneralManager() {super(Handler.NUM_THREE, Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "销假" + leave.getNum() + "天," + leave.getContent() + "!");
System.out.println("总经理审批通过:批准!");
}
}
Client
package com.zhuang.responsibility;
/**
* @Classname Client
* @Description 责任链模式 测试类
* @Date 2021/3/31 16:39
* @Created by dell
*/
public class Client {public static void main(String[] args) {
// 请假条
LeaveRequest leave = new LeaveRequest("小庄", 3, "进来游览");
// 各位领导
Manager manager = new Manager();
GroupLeader groupLeader = new GroupLeader();
GeneralManager generalManager = new GeneralManager();
/*
小组长下属是经理 经理下属是总经理
*/
groupLeader.setNextHandler(manager);
manager.setNextHandler(generalManager);
// 提交
groupLeader.submit(leave);
}
}
27.3 责任链模式的利用场景
- 多个对象能够解决一个申请,但具体由哪个对象解决该申请在运行时主动确定。
- 可动静指定一组对象解决申请,或增加新的解决者。
- 须要在不明确指定申请解决者的状况下,向多个解决者中的一个提交申请。
写在最初
- 如果我的文章对你有用,请给我点个👍,感激你😊!
- 有问题,欢送在评论区指出!💪
正文完