职责链模式
前言
项目中有考勤请假审批这个模块,可以用到职责链模式。
过程
请一天假,请示小组长,请三天假,请示项目经理,请五天及五天以上的假,请示CTO。
提出请假的人便是Client,而组长、经理、CTO三者其实是同一类人,即都是请求处理者(ConcreteHandler),而他们都是抽象的处理者(Handler)的子类。
- Client: 调用者;
- Request: 请求体,用于封装一些请求的信息,有时候判断的因素不只是一个;
- Response: 结果实体,消息处理完封装的结果类;
- Handler: 处理请求的实体类;
- 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
还没有评论,来说两句吧...