设计模式整理(8) 责任链模式

学习《Android 源码设计模式解析与实践》系列笔记

介绍

所谓的链,是指将多个节点首尾相连形成的结构。
编程中的责任链模式,类似于这种结构,将每个节点看作是一个对象,每个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径一次传递,直到有对象处理这个请求为止,我们将这样的模式称为责任链模式。
责任链模式属于行为型设计模式。

定义

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

使用场景

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

结构

1 简单版的责任链模式结构

设计模式整理(8) 责任链模式_第1张图片
责任链模式 UML 图 1
  • Handler : 抽象处理者对象,声明一个请求处理的方法,并持有下一个处理节点 Handler 对象的引用。
  • ConcreteHandler : 具体处理者角色,对请求进行处理,不能处理的则将请求传递给下一个节点的处理者。

简单示例

/**
 * 抽象处理者
 */
public abstract class Handler {

    protected Handler mSuccessor;

    public void setSuccessor(Handler successor) {
        mSuccessor = successor;
    }

    public abstract void handleRequest(String condition);

}
/**
 * 具体的处理者,ConcreteHandler1
 */
public class ConcreteHandler1 extends Handler {
    @Override
    public void handleRequest(String condition) {
        if (condition.equals("ConcreteHandler1")) {
            System.out.println("ConcreteHandler1 handled");
        } else {
            mSuccessor.handleRequest(condition);
        }
    }
}
/**
 * 具体的处理者,ConcreteHandler2
 */
public class ConcreteHandler2 extends Handler {
    @Override
    public void handleRequest(String condition) {
        if (condition.equals("ConcreteHandler2")) {
            System.out.println("ConcreteHandler2 handled");
        } else {
            mSuccessor.handleRequest(condition);
        }
    }
}
/**
 * 具体的处理者,ConcreteHandler3
 */
public class ConcreteHandler3 extends Handler {
    @Override
    public void handleRequest(String condition) {
        if (condition.equals("ConcreteHandler3")) {
            System.out.println("ConcreteHandler3 handled");
        } else {
            mSuccessor.handleRequest(condition);
        }
    }
}
public class Client {

    public static void main(String args[]) {
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        Handler handler3 = new ConcreteHandler3();
        handler1.mSuccessor = handler2;
        handler2.mSuccessor = handler3;
        //处理请求
        handler1.handleRequest("ConcreteHandler3");
    }

}

这里的请求是一个固定的 String 字符串,但是在实际运用中,可能请求的情况会比较复杂,所以这里的请求也可以抽出一个基类,进行封装。

2 改进的责任链模式结构

设计模式整理(8) 责任链模式_第2张图片
责任链模式 UML 图 2

这里增加了 level ,只有处理者和请求的级别一致时,才能处理该请求,不然就交由下一个节点的处理者处理该请求。

简单示例

/**
 * 抽象的请求
 */
public abstract class Request {

    // 需要处理的内容
    private Object mContent;

    public Request(Object content) {
        mContent = content;
    }

    public Object getContent() {
        return mContent;
    }

    public abstract int getRequestLevel();
}
/**
 * 请求的具体实现类,ConcreteRequest1
 */
public class ConcreteRequest1 extends Request {

    public ConcreteRequest1(Object content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return 1;
    }
}
/**
 * 请求的具体实现类,ConcreteRequest2
 */
public class ConcreteRequest2 extends Request {

    public ConcreteRequest2(Object content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return 2;
    }
}
/**
 * 请求的具体实现类,ConcreteRequest3
 */
public class ConcreteRequest3 extends Request {

    public ConcreteRequest3(Object content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return 3;
    }
}
/**
 * 抽象处理者
 */
public abstract class Handler {

    protected Handler mSuccessor;

    public void setSuccessor(Handler successor) {
        mSuccessor = successor;
    }

    public void handleRequest(Request request) {
        if (getHandlerLevel() == request.getRequestLevel()) {
            handle(request);
        } else {
            mSuccessor.handleRequest(request);
        }
    }

    public abstract int getHandlerLevel();

    public abstract void handle(Request request);
}
/**
 * 具体的处理者,ConcreteHandler1
 */
public class ConcreteHandler1 extends Handler {

    @Override
    public int getHandlerLevel() {
        return 1;
    }

    @Override
    public void handle(Request request) {
        System.out.println("ConcreteHandler1 handled");
    }
}
/**
 * 具体的处理者,ConcreteHandler2
 */
public class ConcreteHandler2 extends Handler {
    @Override
    public int getHandlerLevel() {
        return 2;
    }

    @Override
    public void handle(Request request) {
        System.out.println("ConcreteHandler2 handled");
    }
}
/**
 * 具体的处理者,ConcreteHandler3
 */
public class ConcreteHandler3 extends Handler {
    @Override
    public int getHandlerLevel() {
        return 3;
    }

    @Override
    public void handle(Request request) {
        System.out.println("ConcreteHandler3 handled");
    }
}
/**
 * Created by linpu on 2019/2/14 .
 */
public class Client {

    public static void main(String args[]) {
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        Handler handler3 = new ConcreteHandler3();
        handler1.mSuccessor = handler2;
        handler2.mSuccessor = handler3;

        Request request1 = new ConcreteRequest1("Requestq1");
        Request request2 = new ConcreteRequest2("Requestq2");
        Request request3 = new ConcreteRequest3("Requestq3");

        //处理请求
        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
        handler1.handleRequest(request3);
    }

}

实现

XX 需要申请五万的经费。于是他向他的上级,也就是项目组的组长提出申请,但是组长没有权限审批这么大数目的经费。于是,组长找到部门主管,主管一看也超出了自己的权限。于是继续找到上级的经理,经理看了说他只能审批1万以内的数额,所以他拿着审批文件找到了老板。最后老板看了文件后批准了。
在整个申请过程中,申请人 XX 只和组长产生了关联,然后请求就层层的网上传达,他不关心中间的过程,只关心最后的审批结果。所以说,责任链很好的将请求的发起者和处理者进行了解耦。

具体代码如下:

/**
 * 抽象领导者类
 */
public abstract class Leader {

    protected Leader mAccessor;

    public void handleRequest(int money) {
        if (money <= limit()) {
            handler(money);
        } else {
            if (mAccessor != null) {
                mAccessor.handleRequest(money);
            }
        }
    }

    // 最高能批复的额度
    public abstract int limit();

    public abstract void handler(int money);
}
/**
 * 组长类
 */
public class GroupLeader extends Leader {
    @Override
    public int limit() {
        return 1000;
    }

    @Override
    public void handler(int money) {
        System.out.println("组长批复报销:" + money + " 元");
    }
}
/**
 * 主管类
 */
public class Director extends Leader {
    @Override
    public int limit() {
        return 5000;
    }

    @Override
    public void handler(int money) {
        System.out.println("主管批复报销:" + money + " 元");
    }
}
/**
 * 经理类
 */
public class Manager extends Leader {
    @Override
    public int limit() {
        return 10000;
    }

    @Override
    public void handler(int money) {
        System.out.println("经理批复报销:" + money + " 元");
    }
}
/**
 * 老板类
 */
public class Boss extends Leader {
    @Override
    public int limit() {
        return Integer.MAX_VALUE;
    }

    @Override
    public void handler(int money) {
        System.out.println("老板批复报销:" + money + " 元");
    }
}
/**
 * 发起请求的职员
 */
public class Staff {

    public static void main(String args[]) {
        Leader groupLeader = new GroupLeader();
        Leader director = new Director();
        Leader manager = new Manager();
        Leader boss = new Boss();

        groupLeader.mAccessor = director;
        director.mAccessor = manager;
        manager.mAccessor = boss;

        //想组长发起申请
        groupLeader.handleRequest(50000);
    }

}

结果:

老板批复报销:50000 元

总结

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

缺点:
需要对链进行遍历,如果处理者很多,那整个遍历的时间可能就很长,可能会影响性能。



相关文章:

设计模式整理(1) 代理模式
设计模式整理(2) 单例模式
设计模式整理(3) Builder 模式
设计模式整理(4) 原型模式
设计模式整理(5) 工厂模式
设计模式整理(6) 策略模式
设计模式整理(7) 状态模式
设计模式整理(8) 责任链模式
设计模式整理(9) 观察者模式
设计模式整理(10) 适配器模式
设计模式整理(11) 装饰模式
设计模式整理(12) 中介者模式

你可能感兴趣的