Java-责任链-设计模式(十六)

说明

责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连城一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

UML
uml
角色:
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

代码

以张三发起一个请假或加薪的申请为例,审批人有主管,总监,总经理,各自权限不同。
主管:只能处理两天以内的请假请求,其余的转交给上级。
总监:许可一周以内的请假,其余转交给上级。
总经理:所有请假都批准;500以内加薪批准,超出500需要考虑。
此例参考《大话设计模式》,代码如下。

抽象处理者角色

/**
 * @author ctl
 * @date 2021/1/27
 * 管理者
 */
public abstract class Manager {

    protected String name;

    // 上级
    protected Manager superior;

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

    // 设置上级
    public void setSuperior(Manager superior) {
        this.superior = superior;
    }

    // 申请
    public abstract void request(Request request);
}

具体处理者角色,主管

/**
 * @author ctl
 * @date 2021/1/27
 * 主管
 * 权限:只能处理两天以内的请假请求,其余的转交给上级
 */
public class CommonManager extends Manager {

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

    @Override
    public void request(Request request) {
        if ("请假".equals(request.getRequestType()) && request.getNum() <= 2) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 数量" + request.getNum() + " 被批准");
        } else {
            // 转交上级
            if (superior != null) {
                superior.request(request);
            }
        }
    }
}

具体处理者角色,总监

/**
 * @author ctl
 * @date 2021/1/27
 * 总监
 * 权限:许可一周以内的请假
 */
public class Majordomo extends Manager {
    public Majordomo(String name) {
        super(name);
    }

    @Override
    public void request(Request request) {
        if ("请假".equals(request.getRequestType()) && request.getNum() <= 5) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 数量" + request.getNum() + " 被批准");
        } else {
            // 转交上级
            if (superior != null) {
                superior.request(request);
            }
        }
    }
}

具体处理者角色,总经理

/**
 * @author ctl
 * @date 2021/1/27
 * 总经理
 * 权限:最高级,所有类型的请求都处理
 *      请假都批
 *      加薪500以下批,否则需要考虑
 */
public class GeneralManager extends Manager {

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

    @Override
    public void request(Request request) {
        // 请假 都批准
        if ("请假".equals(request.getRequestType())) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 数量" + request.getNum() + " 被批准");
        } else if ("加薪".equals(request.getRequestType()) && request.getNum() <= 500) {
            // 加薪 500以下批准 超过500 考虑考虑
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 数量" + request.getNum() + " 被批准");
        } else if ("加薪".equals(request.getRequestType()) && request.getNum() > 500) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 数量" + request.getNum() + " 需要考虑考虑");
        }
    }
}

申请对象,封装了申请内容

/**
 * @author ctl
 * @date 2021/1/27
 * 申请对象
 */
public class Request {

    // 申请类型
    private String requestType;

    // 申请内容
    private String requestContent;

    // 申请数量
    private int num;

    public String getRequestType() {
        return requestType;
    }

    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public String getRequestContent() {
        return requestContent;
    }

    public void setRequestContent(String requestContent) {
        this.requestContent = requestContent;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

测试类

/**
 * @author ctl
 * @date 2021/1/27
 */
public class ChainMain {

    public static void main(String[] args) {
        CommonManager commonManager = new CommonManager("主管");
        Majordomo majordomo = new Majordomo("总监");
        GeneralManager generalManager = new GeneralManager("总经理");
        // 设置上级,可以按需调整
        commonManager.setSuperior(majordomo);
        majordomo.setSuperior(generalManager);

        // 客户端的每次申请都是由主管发出,内部具体的链路客户端并不知晓
        Request request = new Request();
        request.setRequestType("请假");
        request.setRequestContent("张三请假");
        request.setNum(1);
        commonManager.request(request);

        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("张三请假");
        request2.setNum(4);
        commonManager.request(request2);

        Request request3 = new Request();
        request3.setRequestType("加薪");
        request3.setRequestContent("张三请求加薪");
        request3.setNum(500);
        commonManager.request(request3);

        Request request4 = new Request();
        request4.setRequestType("加薪");
        request4.setRequestContent("张三请求加薪");
        request4.setNum(1000);
        commonManager.request(request4);
    }
}

结果
结果
张三发起申请,只对接主管,最终根据设定的级别权限,所有角色进行了对应的审批。

总结

责任链模式的好处就是接收者和发送者彼此都不知道对方的角色,而且链中的对象自己也不知道链的结构。大大降低了耦合度。并且可以随时按需修改处理一个请求的结构,增强了给对象指派指责的灵活性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值