【面向对象】设计模式之责任链模式的学习

介绍

责任链模式是一种行为模式,它从一个起点发起请求,沿着任务链传递给每个节点的对象,直至有一个节点处理了这个请求。

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

比较类似Android的View的事件分发机制。

使用场景

  • 可以多个对象处理统一请求,具体谁来处理在运行时动态决定
  • 在请求的处理者不明确的情况下,向多个对象的一个提交请求。
  • 需要动态指定一组对象来处理请求。

简单版

img

角色介绍

  • 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进行处理

复杂版

简单版中,传递的都是统一的字符串,处理也比较简单。但实际开发中,责任链中的请求处理规则一般是不同的,这时就需要对请求进行封装,同时对请求的处理规则也进行封装,

img

代码

抽象处理者

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

N0tExpectErr0r

一名热爱代码的 Android 开发者

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>