责任链模式

117 阅读3分钟

本文主要内容

  • 责任链模式简介
  • 责任链模式示例
  • 总结

1、责任链模式简介

什么是链呢?比如说多节铁环串起来就叫链,强调的是,铁环可以自由拆卸安装,都不会影响整个链的使用。责任链模式是一种非常自由的模式

使多个对象都有机会处理请求,从而避免了请求的分发者和接收者之间的耦合。将这些对象形成一条链,并沿着这条链传递该请求,只到有对象处理它为止。

责任链适宜的情况:

  • 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定
  • 在请求处理者不明确的情况下向多个对象中的一个提交一个请求
  • 需要动态指定一组处理处理请求

责任链模式UML图

在android中,有非常多的责任链示例,比如touch事件传递,另外广播也是。曾看过okhttp的源码,它内部也是一个责任链模式,代码非常优雅,有兴趣的同学可以看看。

2、责任链模式示例

我们以单位报销为示例,写一个demo,不同的领导有不同的经费报销权限或者限制,比如小组长只能批复报销1000元,而经理可以批复报销10000,以此为例。

先定义一个领导的抽象类:

public abstract class Leader {

protected Leader nextLeader;

public abstract int limit();

public abstract void handle(int money);

public final void handleRequest(int money){
	if (money < limit()) {
		handle(money);
	}else {
		if (nextLeader != null) {
			nextLeader.handleRequest(money);
		}
	}
}
}

此处必须写一个抽象类,而不能是接口。经常会有人问到,抽象类和接口有什么区别,此处就是区别之一。抽象类中可以有非抽象方法还能定义非静态成员变量,Leader 类中必须要有处理请求的方法handleRequest,而且还是 final 的,子类不能重写,才能保证整个机制的运转。

接下来看小组长类定义:

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() {
	return 5000;
}

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

}

再看看经理的定义:

public class Manager extends Leader{

@Override
public int limit() {
	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 Staff {

public static void main(String[] args) {
	GroupLeader groupLeader = new GroupLeader();
	Director director = new Director();
	Manager manager = new Manager();
	Boss boss = new Boss();
	
	groupLeader.nextLeader = director;
	director.nextLeader = manager;
	manager.nextLeader = boss;
	
	groupLeader.handleRequest(50000);
}
}

整个示例就结束了。责任链模式中的任意一个环节都是可以去掉的,比如上例当中,可以不向老板申请报销,这就是责任链的灵活之处

3、总结

在日常生活中还是要多看各种不同的代码,比如第一次看okhttp的源码,发现其中的责任链模式,我回味了好久,当时就感觉代码非常非常优雅。我们又学到了一种牛逼的代码方式 。