微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

第十六章·职责链模式

一、职责链模式概述

定义:

职责链模式:避免讲一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。

二、职责链模式结构和实现

2.1 职责链模式结构

职责链模式包含2个角色:

  1. Handler(抽象处理者):定义了一个处理请求的接口,定义了一个抽象处理者类型的对象,作为其下家的引用,通过该引用处理者可以连成一条链;
  2. ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户的请求,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者进行处理。

2.2 职责链模式实现

//请假单,充当请求类

/**
 * 请假单
 */
public class WrittenRequest {

    //请假人
    private String username;

    //请假内容
    private String content;

    //请假天数
    private int day;

    public WrittenRequest(String username, String content, int day) {
        this.username = username;
        this.content = content;
        this.day = day;
    }

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        this.day = day;
    }
}

//审批者,充当抽象处理者

/**
 * 抽象审批者
 */
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;
    }

    public abstract void handler(WrittenRequest request);
}

//具体处理者

/**
 * 主任
 */
public class Director extends Approver {


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

    @Override
    public void handler(WrittenRequest request) {
        if (request.getDay() < 3) {
            System.out.println("[主任]" + name + "审批并通过了");
        } else {
            this.successor.handler(request);
        }
    }
}

/**
 * 经理
 */
public class Manager extends Approver {


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

    @Override
    public void handler(WrittenRequest request) {
        if (request.getDay() >= 3 && request.getDay() < 10) {
            System.out.println("[经理]" + name + "审批并通过了");
        } else {
            this.successor.handler(request);
        }
    }
}

/**
 * 总经理
 */
public class GeneralManager extends Approver{

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

    @Override
    public void handler(WrittenRequest request) {
        if (request.getDay() >= 10 && request.getDay() <= 30) {
            System.out.println("[总经理]" + name + "审批并通过了");
        } else {
            System.out.println("请假超过30天,拒绝此申请!");
        }
    }
}

//客户端

public class Client {

    public static void main(String[] args) {

        /**
         * 案例需求描述:
         * 某OA系统需要提供一个假条审批模块;
         * 如果员工请假天数小于3天,主任可以审批该请假条;
         * 如果员工请假天数大于等于3天,小于10天,经理可以审批;
         * 如果员工请假天数大于等于10天,小于等于30天,总经理可以审批;
         * 如果员工请假天数大于30天,则总经理也不可以审批,提示拒绝信息;
         * 请使用职责链模式设计该功能模块。
         */

        WrittenRequest request1 = new WrittenRequest("张三","生病请假",2);
        WrittenRequest request2 = new WrittenRequest("李四","旅游请假",5);
        WrittenRequest request3 = new WrittenRequest("王五","陪产假",23);
        WrittenRequest request4 = new WrittenRequest("赵六","休息请假",31);

        Approver zhangfei,guanyu,liubei;
        zhangfei = new Director("张飞");
        guanyu = new Manager("关羽");
        liubei = new GeneralManager("刘备");

        zhangfei.setSuccessor(guanyu);
        guanyu.setSuccessor(liubei);

        zhangfei.handler(request1);
        zhangfei.handler(request2);
        zhangfei.handler(request3);
        zhangfei.handler(request4);

    }

}

三、职责链模式的优缺点和适用环境

3.1 职责链模式的优点

  1. 使一个对象无需知道是其他哪一个请求对象处理其请求,降低了系统的耦合度;
  2. 简化了对象之间的相互连接;
  3. 给对象职责的分派带来更多的灵活性;
  4. 增加一个新的具体请求处理者较为方便。

3.2 职责链模式的缺点

  1. 不能保证请求一定会被处理;
  2. 对于比较长的职责链,系统性能将受到一定的影响;
  3. 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。

3.3 职责链模式的适用环境

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定;
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
  3. 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。

【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。

【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git

原文地址:https://www.jb51.cc/wenti/3280214.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐