赞
踩
本文参考:
https://www.cnblogs.com/aeolian/p/8888958.html
https://www.cnblogs.com/fengyumeng/p/10839570.html
责任链模式(Chain of Responsibility Pattern)是一种常见的行为模式。
责任链模式英文原话是:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving object and pass the request along the chain until an object handles it.
翻译:使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象串成一条链,并沿着这条链一直传递该请求,直到有对象处理它为止。
责任链模式的重点在“链上”,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果。
角色:
抽象处理者(Handler)角色:该角色对请求进行抽象,并定义一个方法来设定和返回对下一个处理者的引用。
具体处理者(Concrete Handler):该角色接到请求后,可以选择将请求处理掉,或者将请求传给下一个处理者。由于具体处理者持有对下一个处理者的引用,因此,如果需要,处理者可以访问下一个处理者。
如果在公司里,因为病假要请一个月的假需要经过组长、经理等好几轮的审核签字,这跟咱们的责任链模式非常相似,现以请假为例:
角色1:请假条,其实可以理解成请假人,因为请假条上自然有请假人信息。
角色2:领导人,小组长、部门经理、总经理都是审批人。
动作:领导人审批请假条。
流程如下:
请假条抽象:
- public interface ILeave {
- String getName();//请假人姓名
- int getNum();//请假天数
- String getContent();//请假条内容
- }
请假条实现:
- public class Leave implements ILeave{
- private String name;//姓名
- private int num;//请假天数
- private String content;//请假内容
-
- public Leave(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;
- }
- }
领导人抽象:
- public interface IHandler {
- void handleLeave(ILeave leave);//处理请假条
- }
领导人实现:
- public class GroupLeader implements IHandler {
- @Override
- public void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("小组长审批:同意。");
- }
- }
- public class Manager implements IHandler {
- @Override
- public void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("部门经理审批:同意。");
- }
- }
- public class BigManager implements IHandler {
- @Override
- public void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("总经理审批:同意。");
- }
- }
客户端实现:
- public static void main(String[] args) {
- //请假条来一张
- ILeave leave = new Leave("小花",5,"身体不适");
-
- //小组长第一个审批
- IHandler groupLeader = new GroupLeader();
- groupLeader.handleLeave(leave);
-
- if(leave.getNum() >= 3){
- IHandler manager = new Manager();
- manager.handleLeave(leave);
- }
- if(leave.getNum() >= 7){
- IHandler bigManager = new BigManager();
- bigManager.handleLeave(leave);
- }
- }
输出:
小花请假5天,身体不适。
小组长审批:同意。
小花请假5天,身体不适。
部门经理审批:同意。
这个程序是有问题,如果公司修改请假制度,一个月以上的请假需要老板审核签字,就得在客户端实现方法再写个if语句,这显然是有问题的。正确的逻辑应该是什么样的呢? 应该是小花递了请假条之后,就只需要等结果即可,而不是找了这个审批,回来后又跑去找那个审批。
优化:
请假条抽象:
- public interface ILeave {
- String getName();//请假人姓名
- int getNum();//请假天数
- String getContent();//请假条内容
- }
请假条:
- public class Leave implements ILeave{
- private String name;//姓名
- private int num;//请假天数
- private String content;//请假内容
-
- public Leave(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;
- }
- }
领导人抽象:
- 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 = 0;
- private int numEnd = 0;
-
- //领导上面还有领导
- 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(ILeave leave){
- if(0 == this.numStart){
- return;
- }
-
- //如果请假天数达到该领导者的处理要求
- if(leave.getNum() >= this.numStart){
- this.handleLeave(leave);
-
- //如果还有上级 并且请假天数超过了当前领导的处理范围
- if(null != this.nextHandler && leave.getNum() > numEnd){
- this.nextHandler.submit(leave);//继续提交
- }
- }
- }
-
- //各级领导处理请假条方法
- protected abstract void handleLeave(ILeave leave);
- }
领导人实例:
- public class GroupLeader extends Handler {
-
- public GroupLeader() {
- //小组长处理1-3天的请假
- super(Handler.NUM_ONE, Handler.NUM_THREE);
- }
-
- @Override
- protected void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("小组长审批:同意。");
- }
- }
- public class Manager extends Handler {
- public Manager() {
- //部门经理处理3-7天的请假
- super(Handler.NUM_THREE, Handler.NUM_SEVEN);
- }
-
- @Override
- protected void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("部门经理审批:同意。");
- }
- }
- public class BigManager extends Handler {
- public BigManager() {
- //部门经理处理7天以上的请假
- super(Handler.NUM_SEVEN);
- }
-
- @Override
- protected void handleLeave(ILeave leave) {
- System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
- System.out.println("总经理审批:同意。");
- }
- }
客户端:
- public static void main(String[] args) {
- //请假条来一张
- ILeave leave = new Leave("小花",5,"身体不适");
-
- //各位领导
- Handler groupLeader = new GroupLeader();
- Handler manager = new Manager();
- Handler bigManager = new BigManager();
-
- groupLeader.setNextHandler(manager);//小组长的领导是部门经理
- manager.setNextHandler(bigManager);//部门经理的领导是总经理
- //之所以在这里设置上级领导,是因为可以根据实际需求来更改设置,如果实战中上级领导人都是固定的,则可以移到领导实现类中。
-
- //提交申请
- groupLeader.submit(leave);
- }
输出:
小花请假5天,身体不适。
小组长审批:同意。
小花请假5天,身体不适。
部门经理审批:同意。
责任链模式是一种常见的模式,Struts2的核心控件FilterDispatcher是一个Servlet过滤器,该控件就是采用责任链模式,可以对用户请求进行层层过滤处理。责任链模式在实际项目中的使用比较多,其典型的应用场景如下:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。