职责链模式
一、定义
责任链模式:将能够处理同一类请求的对象连成一条链,使这些对象都有机会处理请求,所提交的请求沿着链传递。从而避免请求的发送者和接受者之间的耦合关系。链上的对象逐个判断是否有能力处理该请求,如果能则就处理,如果不能,则传给链上的下一个对象。直到有一个对象处理它为止。
二、职责链模式结构图
三、示例
每一个公司对请假都是控制的很严格,必须要相关的人员签字。三天,主任签字;三到七天,经理签字;一个星期副总经理签字;以上总经理签字。
处理请示的接口
/**
* 抽象类
* @author Administrator
*
*/
public abstract class Leader {
protected String name;
protected Leader nextLeader;//责任链上的后继对象
public Leader(String name) {
super();
this.name = name;
}
//设定责任链后继对象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 处理请求的核心的业务方法
* @param request
*/
public abstract void handleRequest(LeaveRequest request);
}
总经理
/**
* 总经理
* @author Administrator
*
*/
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 30){
System.out.println("员工"+request.getEmpName()+"请假 天数"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("总经理:"+this.name+"审批通过");
}else{
System.out.println("莫非"+request.getEmpName()+"想辞职 居然请假"+request.getLeaveDays()+"天");
}
}
}
副总经理
/**
* 副总经理
* @author Administrator
*
*/
public class ViceGeneralManager extends Leader {
public ViceGeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 20){
System.out.println("员工"+request.getEmpName()+"请假 天数"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("副总经理:"+this.name+"审批通过");
}else{
this.nextLeader.handleRequest(request);
}
}
}
经理
/**
* 经理
* @author Administrator
*
*/
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 10){
System.out.println("员工"+request.getEmpName()+"请假 天数"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("经理:"+this.name+"审批通过");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
主任
/**
* 主任
* @author Administrator
*
*/
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 3){
System.out.println("员工"+request.getEmpName()+"请假 天数"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("主任:"+this.name+"审批通过");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
申请
/**
* 封装请假基本信息
* @author Administrator
*
*/
public class LeaveRequest {
private String empName;
private int leaveDays;
private String reason;
public LeaveRequest(String empName, int leaveDays, String reason) {
super();
this.empName = empName;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
测试
public class Client {
public static void main(String[] args) {
Leader a = new Director("张三");
Leader b = new Manager("李四");
Leader b2 = new ViceGeneralManager("李小四");
Leader c = new GeneralManager("王五");
//组织责任链对象关系
a.setNextLeader(b);
b.setNextLeader(b2);
b2.setNextLeader(c);
//开始请假操作
LeaveRequest req1 = new LeaveRequest("Tom", 10, "回英国老家");
a.handleRequest(req1);
}
}
四、使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
五、模式优缺点
优点
1、降低耦合度。它将请求的发送者和接受者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。
六、模式总结
1、职责链模式将请求的发送者和接受者解耦了。客户端不需要知道请求处理者的明确信息,甚至不需要知道链的结构,它只需要将请求进行发送即可。
2、职责链模式能够非常方便的动态增加新职责或者删除职责。
3、客户端发送的请求可能会得不到处理。
4、处理者不需要知道链的结构,只需要明白他的后续者是谁就可以了。这样就简化了系统中的对象。