模式定义
职责链模式(Chain of Responsibility Pattern):避免请求发送者和接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。它是一种对象行为型模式。
模式结构
职责链模式结构图如下所示:
Handler
抽象处理者定义了一个处理请求的接口,它一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为没一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个自类型的对象,作为对下家的引用,通过该引用,处理者可以连成一条链。ConcreteHandler
具体处理者是抽象处理者的子类,它可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。客户类用于向链中的对象提出最初的请求,客户类只需关系链的源头,而无须关心请求的处理细节以及请求的传递过程。
实例
某OA系统需要提供一个假条审批的模块,如果员工请假天数小于3天,主任可以审批该假条;如果员工请假天数小于3天,主任可以审批;如果大于等于3天,小于10天,经理可以审批;如果大于等于10天,小于30天,总经理可以审批;如果超过30天,总经理也不能审批,提示相应拒绝信息。
下面通过职责链模式模拟该场景,实例类图如下:
public class LeaveRequest {
private String leaveName;
private int leaveDays;
public LeaveRequest(String name, int days) {
this.leaveName = name;
this.leaveDays = days;
}
public void setName(String name) {
this.leaveName = name;
}
public void setLeaveDays(int days) {
this.leaveDays = days;
}
public String getName() {
return this.leaveName;
}
public int getLeaveDays() {
return this.leaveDays;
}
}
public abstract class Leader {
protected String name;
protected Leader successor;
public Leader(String name) {
this.name = name;
}
public void setSuccessor(Leader successor) {
this.successor = successor;
}
public abstract void handleRequest(LeaveRequest request);
}
public class Director extends Leader {
public Director(String name) {
super(name);
}
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 3) {
System.out.println("主任" + name + "审批员工" +
request.getName() +
"的请假条,请假天数为" + request.getLeaveDays + "天");
}
else {
if (null != this.successor)
this.successor.handleRequest();
}
}
}
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 10) {
System.out.println("经理" + name + "审批员工" +
request.getName() +
"的请假条,请假天数为" + request.getLeaveDays + "天");
}
else {
if (null != this.successor)
this.successor.handleRequest();
}
}
}
public class GeneralManager extends Leader {
public Manager(String name) {
super(name);
}
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 30) {
System.out.println("总经理" + name + "审批员工" +
request.getName() +
"的请假条,请假天数为" + request.getLeaveDays + "天");
}
else {
System.out.println("莫非" + request.getName() + "想辞职,居然请假" +
request.getLeaveDays() + "天");
}
}
}
public class Client {
public static void main(String[] args) {
Leader objDirector, objManager, objGeneralManager;
objDirector = new Director("张三");
objManager = new Manager("李四");
objGeneralManager = new GeneralManager("王五");
objDirector.setSuccessor(objManager);
objManager.setSuccessor(objGeneralManager);
LeaveRequest r1 = new LeaveRequest("顺溜", 2);
objDirector.handleRequest(r1);
LeaveRequest r2 = new LeaveRequest("王胖子", 5);
objDirector.handleRequest(r2);
LeaveRequest r3 = new LeaveRequest("闷油瓶", 12);
objDirector.handleRequest(r3);
LeaveRequest r4 = new LeaveRequest("吴邪", 5);
objDirector.handleRequest(r4);
}
}