职责链模式

前言

项目中有考勤请假审批这个模块,可以用到职责链模式。

过程

请一天假,请示小组长,请三天假,请示项目经理,请五天及五天以上的假,请示CTO。

提出请假的人便是Client,而组长、经理、CTO三者其实是同一类人,即都是请求处理者(ConcreteHandler),而他们都是抽象的处理者(Handler)的子类。

 

  1. Client: 调用者;
  2. Request: 请求体,用于封装一些请求的信息,有时候判断的因素不只是一个;
  3. Response: 结果实体,消息处理完封装的结果类;
  4. Handler: 处理请求的实体类;
  5. Level: 等级类,用于保存当前等级的一些消息,如果逻辑简单可以和Request类合并;

编码时刻

Handler:

public abstract class Handler {

    //指向下一个处理类
    private Handler nextHandler;

    public final Response handleMessage(Request request) {
        Response response = null;

        //判断是否是自己的处理等级
        if (request.getLevel().getDay() <= this.getHandlerLevel().getDay()) {
            //是自己的处理等级,就将其进行处理
            response = this.echo(request);
        } else {

            //如果还有下一个handler
            if (this.nextHandler != null) {
                //如果有就让下一个handler进行处理
                response = this.nextHandler.handleMessage(request);
            } else {
                //没有适当的处理者,由调用者自己处理,获取不处理
            }

        }

        return response;

    }

    /**
     * @Description 设置下一个handler处理类
     * @version
     */
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * @Description 模版方法,由子类决定当前实现的实体类是什么等级
     * @version
     */
    protected abstract Level getHandlerLevel();

    /**
     * @Description 对任务的具体处理操作
     * @version
     */
    protected abstract Response echo(Request request);
}
public class CTOHandler extends Handler {
    @Override
    public Level getHandlerLevel() {
        return new Level("技术总监", 5);
    }
    @Override
    public Response echo(Request request) {
        return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
    }
}
public class ManagerHandler extends Handler {
    @Override
    public Level getHandlerLevel() {
        return new Level("经理",3);
    }
    @Override
    public Response echo(Request request) {
        return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
    }
}
public class TeamLeaderHandler extends Handler {
    @Override
    public Level getHandlerLevel() {
        return new Level("组长", 1);
    }
    @Override
    public Response echo(Request request) {
        return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
    }
}

在Handler中,由handleMessage方法进行判断是否交由当前的handler进行处理,在这个抽象类中使用了模版方法(getHandlerLevel和echo),将Handler的等级和处理逻辑延迟到子类进行处理。所以子类的handler只需要处理好当前自己等级的逻辑即可,然后基类的handler做好链的调用逻辑处理(即什么情况交由当前handler,什么情况传递下一个处理),最后等待拼装成链给到用户(即例子中的请假人)使用。
接下来看下请求类、结果类、等级类:

public class Request {
    private Level mLevel;
    public Request(Level mLevel) {
        this.mLevel = mLevel;
    }
    public Level getLevel() {
        return this.mLevel;
    }
}
public class Response {
    private String content;
    public Response(String content) {
        this.content = content;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}
public class Level {
    private String levelName;
    private int day;
    public Level(String levelName, int day) {
        this.levelName = levelName;
        this.day = day;
    }
    public Level(int day) {
        this.day = day;
    }
    public String getLevelName() {
        return levelName;
    }
    public void setLevelName(String levelName) {
        this.levelName = levelName;
    }
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        this.day = day;
    }
}

这几个类比较简单,只是常规的bean,在真正的使用中,可能会减少也有可能会增多,这个视情况而定。
最后就是使用职责链了,这里使用了一个ResponChainHelper辅助类,进行职责链的拼装,让client无需知道拼装过程。从client类中,可看到,这时只需要获取到职责链的handler,实例化一个request,交由handler处理即可,至于谁处理,对于用于来说是透明的。

public class ResponChainHelper {
    public static Handler getResChain() {
        Handler ctoHandler = new CTOHandler();
        Handler managerHandler = new ManagerHandler();
        Handler teamLeaderHandler = new TeamLeaderHandler();

        teamLeaderHandler.setNextHandler(managerHandler);
        managerHandler.setNextHandler(ctoHandler);
        return teamLeaderHandler;
    }
}
public class Client {

    public static void main(String[] args) {
        Handler handler = ResponChainHelper.getResChain();

        System.out.println("我想要请一天假:");
        Request request1 = new Request(new Level(1));
        Response response1 = handler.handleMessage(request1);
        System.out.println(response1.getContent());

        System.out.println("我想要请三天假:");
        Request request2 = new Request(new Level(3));
        Response response2 = handler.handleMessage(request2);
        System.out.println(response2.getContent());

        System.out.println("我想要请五天假:");
        Request request3 = new Request(new Level(5));
        Response response3 = handler.handleMessage(request3);
        System.out.println(response3.getContent());
    }

}

如何扩展

如果此时,需求变动,需要增加一项:请假10天的需要CEO批准(这里只是打个比方,现实的CEO很忙不会有空管理这些事),只需要继承handler,然后编写自己需要处理的逻辑,最后在helper中加入到指责链,其余的所有代码都无需改动。

public class CEOHandler extends Handler {
    @Override
    protected Level getHandlerLevel() {
        return new Level("CEO", 10);
    }
    @Override
    protected Response echo(Request request) {
        return new Response("我是" + getHandlerLevel().getLevelName() + ",我准了!");
    }
}
public class ResponChainHelper {
    public static Handler getResChain() {
        Handler ctoHandler = new CTOHandler();
        Handler managerHandler = new ManagerHandler();
        Handler teamLeaderHandler = new TeamLeaderHandler();
        Handler ceoHandler = new CEOHandler();

        teamLeaderHandler.setNextHandler(managerHandler);
        managerHandler.setNextHandler(ctoHandler);
        ctoHandler.setNextHandler(ceoHandler);
        return teamLeaderHandler;
    }
}

借鉴:https://www.jianshu.com/p/d20a314039ef

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值