设计模式-责任链模式
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)
责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请
求,并返回相应的结果。
对上面字面意思理解可能很模糊,我们举一个简单例子。
以员工请假为例,老板可以批假5天,经理可以批假3天,组长可以批假1天。
Handler
/**
* @author shuliangzhao
* @Title: Handler
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:01
*/
public abstract class Handler {
public final static int BOSS_LEAVE = 5;
public final static int MANAGER_LEAVE = 3;
public final static int GROUP_LEADER_LEAVE = 1;
private int level;
public Handler(int level) {
this.level = level;
}
//责任传递,下一责任人
private Handler nextHandler;
public final void handlerMessage(Employee employee) {
if (employee.getLeave() == level) {
this.response(employee);
}else {
if (this.nextHandler != null) {
if (this.nextHandler.level == employee.getLeave()) {
this.nextHandler.response(employee);
}else {
System.out.println("没人批准了,请准确提假期天数");
}
}else {
System.out.println("没人批准了,请准确提假期天数");
}
}
}
public void setHandler(Handler handler) {
this.nextHandler = handler;
}
public abstract void response(Employee employee);
}
Boss
/**
* @author shuliangzhao
* @Title: Boss
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:21
*/
public class Boss extends Handler {
public Boss() {
super(BOSS_LEAVE);
}
@Override
public void response(Employee employee) {
System.out.println("员工找老板请假");
System.out.println(employee.getRequest());
System.out.println("老板同意批假" + BOSS_LEAVE + "天");
}
}
Manager
/**
* @author shuliangzhao
* @Title: Manager
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:24
*/
public class Manager extends Handler {
public Manager() {
super(MANAGER_LEAVE);
}
@Override
public void response(Employee employee) {
System.out.println("员工找经理请假");
System.out.println(employee.getRequest());
System.out.println("经理同意批假" + MANAGER_LEAVE + "天");
}
}
GroupLeader
/**
* @author shuliangzhao
* @Title: GroupLeader
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:26
*/
public class GroupLeader extends Handler {
public GroupLeader() {
super(GROUP_LEADER_LEAVE);
}
@Override
public void response(Employee employee) {
System.out.println("员工找组长请假");
System.out.println(employee.getRequest());
System.out.println("组长同意批假" + GROUP_LEADER_LEAVE + "天");
}
}
Employee
/**
* @author shuliangzhao
* @Title: Employee
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:05
*/
public class Employee {
//请假
private int leave;
private String request;
public Employee(int leave,String request) {
this.leave = leave;
this.request = request;
}
public int getLeave() {
return leave;
}
public void setLeave(int leave) {
this.leave = leave;
}
public String getRequest() {
return request;
}
}
客户端
/**
* @author shuliangzhao
* @Title: Client
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/11 23:29
*/
public class Client {
public static void main(String[] args) {
Handler boss = new Boss();
Handler manager = new Manager();
Handler groupLeader = new GroupLeader();
boss.setHandler(manager);
manager.setHandler(groupLeader);
Employee employee = new Employee(6,"端午节回家");
boss.handlerMessage(employee);
}
}
运行结果
抽象的处理者实现三个职责:一是定义一个请求的处理方法handlerMessage,唯一对外开放的方法;二是定义一个链的编排方法setNext,设置下一个处理者;三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的请假天数getHandlerLeave和具体的处理任务response。
责任链优点:
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处
理者可以不用知道请求的全貌。
责任链缺点:
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别
是在链比较长的时候,性能是一个非常大的问题。二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。