【23种设计模式之责任链模式实战】--请假审批

什么是责任链模式?
    责任链模式:如果有多个对象都有机会处理某个请求
    (至少有一个我们需要关注的指标,如,是否满足某个价格等),
    责任链可以使请求的发送者与接受者解耦,请求沿责任链传递,直到有一个处理了它为止
    责任链,顾名思义:判断是不是我的责任,如果是,处理请求,否则扔给下一个,
    下一个对象判断是不是它的责任,如果不是,继续扔,直到有一个对象处理了该请求为止
    of course,责任链,既然是链,那么这个链可以是线性的,也可以是环状的,也可是树形
    毕竟你是上帝,下面的子民长得咋滴,你想怎么设计就怎么设计,你说了算图片

    如:公司员工提交了申请的申请,可能要经过技术副组长-->技术组长-->小领导-->大领导
    的审批才能通过申请。这个过程,可能技术副组长就有这个资格,直接通过了申请
    也可能技术副组长和技术组长都没资格,小领导甚至是大领导才有资格

优点:
  1、降低耦合度。它将请求的发送者和接收者解耦。
  2、简化了对象。使得对象不需要知道链的结构。
  3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许
   动态地新增或者删除责任链中的节点。
  4、增加新的请求处理类很方便。

缺点:
 1、不能保证请求一定被接收。
 2、请求从链的开头进行遍历,对性能有一定的损耗
 3、在进行代码调试时不太方便,可能会造成循环调用。
 4、可能不容易观察运行时的特征,有碍于除错。

1、在不明确指定接收者的情况下,提交一个请求给多个对象处理。
2、可动态指定一组对象处理某个请求,具体哪个对象处理该请求由运行时刻自动确定。
3、在使用策略模式的地方,可以考虑用责任链

在JAVA WEB中有些运用:
如:Interceptor拦截器,servlet中的Filter过滤器、FilterChain过滤器链

在这里插入图片描述

package design_pattern.chain;
/**
 * 审批人
 * 核心目标:
 *  1.要实现链条,必须知道下个一个,所以要内置后续审批人属性
 *  2.审批人有审批通过和不通过,满足条件通过则结束,不通过则交个下一个,该实现逻辑由子类去实现
 *    父类只定义方法参数,父类的方法参数如果是对象类型,则该参数一般也是抽象类或接口,这叫面向抽象/接口编程
 */
public abstract class Approver {
    //后续审批人
    protected Approver successor;
    //审批人姓名
    protected String name;

    public Approver(String name) {
        this.name = name;
    }

    public void setSuccessor(Approver successor) {
        this.successor = successor;
    }

    /**
     * 处理申请请求的抽象方法 有请假申请、有提薪申请等等,所以这里应该使用抽象解耦
     * 面向对象、面向接口、面向抽象、面向切面编程
     * @param request
     */
    public abstract void doRequest(Request request);
}
package design_pattern.chain;

/**
 * 技术副组长:申请天数1~3天交给技术副组长
 */
public class DeputyGroupLeaderApprover extends Approver {

    public DeputyGroupLeaderApprover(String name) {
        super(name);
    }

    @Override
    public void doRequest(Request request) {
        if (request.getNums()>= 1 && request.getNums() <= 3) {//如果有审批资格
            System.out.println(String.format("%s,审批通过,审批人:%s",request.toString(),name));
        } else {//否则扔给下一个审批人
            if(successor!=null)
               successor.doRequest(request);
        }
    }
}

package design_pattern.chain;

/**
 * 技术组长:申请天数4~6天交给技术组长
 */
public class GroupLeaderApprover extends Approver {

    public GroupLeaderApprover(String name) {
        super(name);
    }
    @Override
    public void doRequest(Request request) {
        if (request.getNums()>= 4 && request.getNums() <= 6) {//如果有审批资格
            System.out.println(String.format("%s,审批通过,审批人:%s",request.toString(),name));
        } else {//否则扔给下一个审批人
            if(successor!=null)
                successor.doRequest(request);
        }
    }
}

package design_pattern.chain;

/**
 * 小领导:申请天数7~9天交给小领导
 */
public class SmallLeaderApprover extends Approver {

    public SmallLeaderApprover(String name) {
        super(name);
    }
    @Override
    public void doRequest(Request request) {
        if (request.getNums()>= 7 && request.getNums() <= 9) {//如果有审批资格
            System.out.println(String.format("%s,审批通过,审批人:%s",request.toString(),name));
        } else {//否则扔给下一个审批人
            if(successor!=null)
                successor.doRequest(request);
        }
    }
}
package design_pattern.chain;

/**
 * 大领导:申请天数10~12天交给大领导
 */
public class BigLeaderApprover extends Approver {

    public BigLeaderApprover(String name) {
        super(name);
    }
    @Override
    public void doRequest(Request request) {
        if (request.getNums()>= 10 && request.getNums() <= 12) {
            System.out.println(String.format("%s,审批通过,审批人:%s",request.toString(),name));
        } else {//否则扔给下一个审批人
            if(successor!=null)
                successor.doRequest(request);
        }
    }
}

面向对象四大特性:封装、继承、多态、抽象

第一步:将请求封装成对象,是对象就要考虑属性和行为【方法】

package design_pattern.chain;

import java.time.LocalDateTime;
import java.util.StringJoiner;

/**
 * 面向对象四大特性:封装、继承、多态、抽象
 * 第一步:将请求封装成对象,是对象就要考虑属性和行为【方法】
 */
public abstract class Request {
    //申请人
    protected String name;
    //申请时间
    protected LocalDateTime applyTime;
    //申请原因
    protected String reason;
    //申请天数
    protected int nums;

    public Request(){

    }
    public Request(String name, LocalDateTime applyTime, String reason, int nums) {
        this.name = name;
        this.applyTime = applyTime;
        this.reason = reason;
        this.nums = nums;
    }

    public int getNums() {
        return nums;
    }

    /**
     * 申请类型
     */
    public abstract String applyType();

    @Override
    public String toString() {
        return new StringJoiner(", ", Request.class.getSimpleName() + "[", "]")
                .add("申请人='" + name + "'")
                .add("申请时间=" + applyTime)
                .add("申请原因='" + reason + "'")
                .add("申请数量=" + nums)
                .toString();
    }
}
package design_pattern.chain;

import java.time.LocalDateTime;

public class AskForLeaveRequest extends Request {

    public AskForLeaveRequest(String name, LocalDateTime applyTime, String reason, int nums) {
        super(name, applyTime, reason, nums);
    }

    @Override
    public String applyType() {
        return "请假成申请";
    }
}

package design_pattern.chain;
import java.time.LocalDateTime;
public class MainTest {
    public static void main(String[] args) {
        Approver deputy= new DeputyGroupLeaderApprover("技术副组长");
        Approver group= new GroupLeaderApprover("技术组长");
        Approver small= new SmallLeaderApprover("小领导");
        Approver big= new BigLeaderApprover("大领导");
        //设置后续申请人
        deputy.setSuccessor(group);
        group.setSuccessor(small);
        small.setSuccessor(big);
        big.setSuccessor(null);
        //发起申请
        Request request = new AskForLeaveRequest("张三",LocalDateTime.now(),"生病请假",5);
        deputy.doRequest(request);
        //由于我们使用的是面向抽象编程,
        // 后期如果张三有调薪的请求,只需要新增一个调薪类,然后实体类替换即可
        //原有的代码不用改动,只需要替换一处,体现了开闭原则
    }
}

结果

在这里插入图片描述

学到了就要教人,赚到了就要给人!
The more I think, the luckier I am.
【越思考,越幸运】
斗皇强者,恐怖如斯,嘿嘿~~

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值