责任链模式
介绍
责任链模式是行为型设计模式之一。链则代表链式调用,采用链式调用方式,让调用者和处理者解偶。比如android中的有序广播,谁处理了后调用abortBroadcast()就可以终止了。不用说Android中的有序广播就用到了此模式了
UML
使用场景
- 多个对象都可以处理同一个请求,但是由哪个对象处理在运行时决定
- 请求处理这不明确的情况下向多个对象中的一个提交请求
- 需要动态指定一组对象处理请求
事件
比如有一个任务分发下来,任务是分等级的,我能处理等一的任务,组长能处理等级二的任务,Leader能处理等级三的任务,那么就形成了一下代码:
- 定义责任链处理者接口
/**
* 责任链处理者
*/
public interface IChainHandle {
/**
* 获取可处理的等级
*
* @return
*/
int getLevel();
/**
* 请求方法
*
* @param thingLevel 事件等级
* @param thing 事件
*/
void request(int thingLevel, String thing);
}
- 各个处理者的实现
/**
* 本人处理者,能处理等级为1的事件
*/
public class MeHandle implements IChainHandle {
private MeHandle() {
}
public static MeHandle create() {
return new MeHandle();
}
/**
* 持有下一个处理者
*/
private IChainHandle iChainHandle;
/**
* 设置下一个责任链
*
* @param iChainHandle
*/
public void setiChainHandle(IChainHandle iChainHandle) {
this.iChainHandle = iChainHandle;
}
@Override
public int getLevel() {
return 1;
}
/**
* 接收请求
*
* @param thingLevel 事件等级
* @param thing 事件
*/
@Override
public void request(int thingLevel, String thing) {
if (getLevel() == thingLevel) {
System.out.println(this.getClass().getSimpleName() + "处理啦");
return;
}
if (iChainHandle != null) {
iChainHandle.request(thingLevel, thing);
} else {
System.out.println("放弃处理,最后收到" + this.getClass().getSimpleName());
}
}
}
/**
* 组长能处理等级为2的事件
*/
public class GroupLHander implements IChainHandle {
private GroupLHander() {
}
public static GroupLHander create() {
return new GroupLHander();
}
/**
* 持有下一个处理者
*/
private IChainHandle iChainHandle;
/**
* 设置下一个责任链
*
* @param iChainHandle
*/
public void setiChainHandle(IChainHandle iChainHandle) {
this.iChainHandle = iChainHandle;
}
@Override
public int getLevel() {
return 2;
}
/**
* 接收请求
*
* @param thingLevel 事件等级
* @param thing 事件
*/
@Override
public void request(int thingLevel, String thing) {
if (getLevel() == thingLevel) {
System.out.println(this.getClass().getSimpleName() + "处理啦");
return;
}
if (iChainHandle != null) {
iChainHandle.request(thingLevel, thing);
} else {
System.out.println("放弃处理,最后收到" + this.getClass().getSimpleName());
}
}
}
/**
* PL处理等级为3的事件
*/
public class PLHandler implements IChainHandle {
private PLHandler() {
}
public static PLHandler create() {
return new PLHandler();
}
/**
* 持有下一个处理者
*/
private IChainHandle iChainHandle;
/**
* 设置下一个责任链
*
* @param iChainHandle
*/
public void setiChainHandle(IChainHandle iChainHandle) {
this.iChainHandle = iChainHandle;
}
@Override
public int getLevel() {
return 3;
}
/**
* 接收请求
*
* @param thingLevel 事件等级
* @param thing 事件
*/
@Override
public void request(int thingLevel, String thing) {
if (getLevel() == thingLevel) {
System.out.println(this.getClass().getSimpleName() + "处理啦");
return;
}
if (iChainHandle != null) {
iChainHandle.request(thingLevel, thing);
}else{
System.out.println("放弃处理,最后收到"+this.getClass().getSimpleName());
}
}
}
- 进行测试
public static void main(String[] args) {
//创建处理者
MeHandle meHandle = MeHandle.create();
GroupLHander groupLHander = GroupLHander.create();
PLHandler plHandler = PLHandler.create();
//这是责任链
meHandle.setiChainHandle(groupLHander);
groupLHander.setiChainHandle(plHandler);
//入口都是我,先来个等级二的再来个等级1的任务
meHandle.request(2, "666");
meHandle.request(1, "666");
}
输出:
GroupLHander处理啦
MeHandle处理啦
如上代码还是挺简单的,基本的责任链思想就是如此了,其中对于请求也可以再利用抽象进行扩展,那么就会变得复杂些了。
Android中的像Touch事件分发、Key事件分发,有序广播就使用到了责任链模式。
总结:责任链模式将请求者和发起者成功解偶,可中途随时某个节点中断或者开始。使用上,就如使用场景说提到,有多个处理者,不知道哪个处理的情况下,就可以想想使用责任链模式,如果多个处理者都需要处理,那么可以考虑用观察者模式了,当然责任链模式这里也可以使用成观察者(全都接收,不处理的则不处理),责任链也可以看成是订阅的一种方式,根据具体场景择优就好。