职责链模式

一、定义

责任链模式:将能够处理同一类请求的对象连成一条链,使这些对象都有机会处理请求,所提交的请求沿着链传递。从而避免请求的发送者和接受者之间的耦合关系。链上的对象逐个判断是否有能力处理该请求,如果能则就处理,如果不能,则传给链上的下一个对象。直到有一个对象处理它为止。

二、职责链模式结构图

 职责链模式

三、示例

每一个公司对请假都是控制的很严格,必须要相关的人员签字。三天,主任签字;三到七天,经理签字;一个星期副总经理签字;以上总经理签字。

 处理请示的接口

/**
 * 抽象类
 * @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、处理者不需要知道链的结构,只需要明白他的后续者是谁就可以了。这样就简化了系统中的对象。