设计模式之责任链模式
责任链模式是一种行为模式,它从一个起点发起请求,沿着任务链传递给每个节点的对象,直至有一个节点处理了这个请求。
它使得多个对象都有机会来处理请求,避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它。
比较类似Android的View的事件分发机制。
使用场景
- 可以多个对象处理统一请求,具体谁来处理在运行时动态决定
- 在请求的处理者不明确的情况下,向多个对象的一个提交请求。
- 需要动态指定一组对象来处理请求。
简单版
角色介绍
- Handler:抽象的处理者,它内部有处理请求的handleRequest方法,并且持有对下一个节点的引用。
- ConcreteHandler: 具体的处理者,实现了handleRequest方法,如果不处理则将请求发送给下一个节点的对象。
代码
抽象处理者
public abstract class Resolver {
protected Resolver nextReceiver;
public abstract void solveRequest(String condition);
public void setNextResolver(Resolver resolver){
nextReceiver = resolver;
}
}
实际处理者1
public class ConcreateResolver1 extends Resolver{
@Override
public void solveRequest(String condition) {
if ("Resolver1".equals(condition)){
System.out.println("Resolver1 solved this Request");
}else {
nextReceiver.solveRequest(condition);
}
}
}
实际处理者2
public class ConcreateResolver2 extends Resolver{
@Override
public void solveRequest(String condition) {
if ("Resolver2".equals(condition)){
System.out.println("Resolver2 solved this request");
}else {
nextReceiver.solveRequest(condition);
}
}
}
客户端
public class Client {
public static void main(String[] args) {
ConcreateResolver1 resolver1 = new ConcreateResolver1();
ConcreateResolver2 resolver2 = new ConcreateResolver2();
resolver1.setNextResolver(resolver2);
resolver2.setNextResolver(resolver1);
resolver1.solveRequest("Resolver2");
}
}
客户端调用结果
Resolver2 solved this request
可以看到,condition不满足实际处理者1的处理规则,因此处理者1将事件发给了处理者2进行处理
复杂版
简单版中,传递的都是统一的字符串,处理也比较简单。但实际开发中,责任链中的请求处理规则一般是不同的,这时就需要对请求进行封装,同时对请求的处理规则也进行封装,
代码
抽象处理者
public abstract class AbstractResolver {
protected AbstractResolver nextResolver;
public final void solveRequest(AbstractRequest request) {
if (request.getRequestLevel() == getSolveLevel()) {
solve(request);
} else {
if (nextResolver != null) {
nextResolver.solveRequest(request);
} else {
System.out.println("无法处理这个请求");
}
}
}
protected abstract int getSolveLevel();
protected abstract void solve(AbstractRequest request);
}
抽象请求
public abstract class AbstractRequest {
private Object obj;
public AbstractRequest(Object obj) {
this.obj = obj;
}
public Object getContent() {
return obj;
}
public abstract int getRequestLevel();
}
三个请求(省略后两个)
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
三个处理者(省略后两个)
public class Resolver1 extends AbstractResolver{
@Override
protected int getSolveLevel() {
return 1;
}
@Override
protected void solve(AbstractRequest request) {
System.out.println("Resolver1处理了请求:"+request.getRequestLevel());
}
}
客户端调用
public class Client {
public static void main(String[] args){
//创建处理者
AbstractResolver resolver1 = new Resolver1();
AbstractResolver resolver2 = new Resolver2();
AbstractResolver resolver3 = new Resolver3();
//串为链
resolver1.nextResolver = resolver2;
resolver2.nextResolver = resolver3;
//三个请求
AbstractRequest request1 = new Request1("A");
AbstractRequest request2 = new Request2("B");
AbstractRequest request3 = new Request3("C");
resolver1.solveRequest(request1);
resolver1.solveRequest(request2);
resolver1.solveRequest(request3);
}
}
客户端运行结果
Resolver1处理了请求:1
Resolver2处理了请求:2
Resolver3处理了请求:3
总结
- 优点
- 降低耦合度,便于拓展,提高代码灵活性。
- 责任链对象互相链接,只用对头部发起请求。
- 缺点
- 如果责任链太长,或者每条链判断处理的时间太长会影响性能。特别是递归循环的时候。
- 请求不一定能得到处理,可能会没有对象处理。
广告时间
我是N0tExpectErr0r,一名广东工业大学的大二学生
欢迎来到我的个人博客,所有文章均在个人博客中同步更新哦
http://blog.N0tExpectErr0r.cn