行为型(三)— 责任链模式

1、介绍

多个节点首尾相连多构成的模型称为链。将这种结构应用到编程领域,将每个节点看作是一个对象,将一个请求对链式的首端发出,沿着链的路径传递给每一个节点对象,直到有对象处理了该请求为止,这种模式称为责任链模式。

2、定义

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.

使得对个对象有机会处理请求,从而避免了请求的发送者和接收者之间的耦合性关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

3、使用场景

  1. 一个请求需要一系列的处理工作
  2. 业务流的处理,例如:文件审批
  3. 多个对象可以处理同一请求,但需运行时动态决定哪个对象处理该请求

4、UML类图


角色说明:

  1. Handler:抽象处理者对象,声明了处理处理请求的方法,并保持 下一个处理者的引用
  2. ConcreteHandler:具体的处理者对象,处理请求,不能处理则传递给下一一下处理者进行处理

5、示例

小明出差深圳一个月回来需要报销费用5万,小明的直接向组长申请报销费用,由于组长的权限是1000,所以组长拿着报销单得向主管申请,但是主管的权限是5000,于是主管又去找经理,但是经理的最高审批额度是1w,经理又去找大boss进行审批,小明只需将报销单给组长,无需关心谁最终审批,责任链模式很好地将请求者和处理者进行解耦。具体代码如下:

/**
 * 抽象处理者
 */
public abstract class Leader {
	protected Leader nextHandler;
	/**
	 * 处理报账请求
	 * @param money  
	 */
	public void handleRequest(int money){
		if (money <= limit()){
			handle(money);
		} else {
			if (nextHandler != null) {
				nextHandler.handleRequest(money);
			}
		}
	}
	/**
	 * 返回自身能够审批的额度
	 * @return
	 */
	public abstract int limit();
	/**
	 * 处理报账行为
	 * @param money  具体金额
	 */
	public abstract void handle(int money);

}
/**
 * 具体的处理者
 */
public class GroupLeader extends Leader {

	@Override
	public int limit() {
		return 1000;
	}

	@Override
	public void handle(int money) {
		System.out.println("组长批复报销:" + money + "元");
	}

}
/**
 * 具体的处理者
 */
public class Director extends Leader {

	@Override
	public int limit() {
		// TODO Auto-generated method stub
		return 5000;
	}

	@Override
	public void handle(int money) {
		System.out.println("主管批复报销:" + money + "元");
	}
}
/**
 * 具体的处理者
 */
public class Manager extends Leader {

	@Override
	public int limit() {
		// TODO Auto-generated method stub
		return 10000;
	}

	@Override
	public void handle(int money) {
		System.out.println("经理批复报销:" + money + "元");

	}
}
/**
 * 具体的处理者
 */
public class Boss extends Leader {

	@Override
	public int limit() {
		return Integer.MAX_VALUE;
	}

	@Override
	public void handle(int money) {
		System.out.println("老板批复报销:" + money + "元");

	}
}
/**
 * 客户端模拟小明的报销流程
 */
public class Client {
	public static void main(String[] args) {
		// 构造各个领导者
		GroupLeader groupLeader = new GroupLeader();
		Director director = new Director();
		Manager manager = new Manager();
		Boss boss = new Boss();
		// 构造链,这个每一个处理者的下个处理对象
		groupLeader.nextHandler = director;
		director.nextHandler = manager;
		manager.nextHandler = boss;
		// 发起报销流程
		groupLeader.handleRequest(50000);
	}
}

输出结果如下:

老板批复报销:50000元

6、总结

优点:请求者和处理者解耦,提高了代码的灵活性

缺点:

  1. 降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长时,性能下降
  2. 不易于调试,由于采用了类似递归的方式,调试逻辑较为复杂

猜你喜欢

转载自blog.csdn.net/zcjxaiofeizhu/article/details/80722576