Java/Android 设计模式系列(15)--责任链模式

  这篇博客我们来介绍一下责任链模式(Chain-of-responsibility Pattern),责任联模式又称为职责链模式,是行为型设计模式之一。顾名思义,责任链模式中存在一个链式结构,多个节点首尾相连,每个节点都可以被拆开再连接,因此,链式结构具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首段发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,这就是责任链或者职责链的通俗定义。

设计模式总目录

  Java/Android 设计模式系列–目录

特点

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

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

UML类图

  责任链模式的 uml 图如下所示:
  这里写图片描述
责任链模式有两大角色:

  • Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持对下一个处理节点 Hanlder 对象的引用;
  • ConcreteHandler:

对于请求 Request 来说,在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,如上图所示。据此可以写出通用代码,首先是 Handler 角色:
AbstractHandler.class

public abstract class AbstractHandler {
    protected AbstractHandler nextHandler;

    public final void handleRequest(AbstractRequest request) {
        if (getHandlerLevel() == request.getLevel()) {
            handle(request);
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.print("there is no handler that can handle this request");
            }
        }
    }

    protected abstract int getHandlerLevel();

    protected abstract void handle(AbstractRequest request);
}

ConcreteHandler1.class

public class ConcreteHandler1 extends AbstractHandler{
    @Override
    protected int getHandlerLevel() {
        return 1;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.print("ConcreteHandler1 handle this request : " + request.getContent() + "\n");
    }
}

ConcreteHandler2.class

public class ConcreteHandler2 extends AbstractHandler{
    @Override
    protected int getHandlerLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.print("ConcreteHandler2 handle this request : " + request.getContent() + "\n");
    }
}

然后是请求角色:
AbstractRequest.class

public abstract class AbstractRequest {

    private Object object;

    public AbstractRequest(Object object) {
        this.object = object;
    }

    public Object getContent() {
        return object;
    }

    public abstract int getLevel();
}

ConcreteRequest1.class

public class ConcreteRequest1 extends AbstractRequest{

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

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

ConcreteRequest2.class

public class ConcreteRequest2 extends AbstractRequest{

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

    @Override
    public int getLevel() {
        return 2;
    }
}

最后客户端测试代码:

public class Client {
    public static void main(String[] args) {
        AbstractHandler handler1 = new ConcreteHandler1();
        AbstractHandler handler2 = new ConcreteHandler2();
        handler1.nextHandler = handler2;

        AbstractRequest request1 = new ConcreteRequest1("request1");
        AbstractRequest request2 = new ConcreteRequest2("request2");

        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
    }
}

结果如下:
这里写图片描述

示例与源码

  其实责任链模式在实际项目过程中遇到的非常多,AndroidJava 源码也一样,举几个简单的例子:

  1. ViewGroup 和 View 中 touch 事件的分发,子 View 的 onTouchEvent 返回 true 代码消费该事件并不再传递,false 代表不消费并且传递到父 ViewGroup 去处理,这些树形结构的子 View 就是责任链上一个个处理对象;
  2. OrderedBroadcast,广播的每一个接收者按照优先级依次接受消息,如果处理完成之后可以调用 abortBroadcast 终止广播,不是自己处理的就可以传递给下一个处理者;
  3. try-catch语句,每一个 catch 根据 Exception 类型进行匹配,形成一个责任链,如果有一个 catch 语句与该 Exception 符合,这个 Exception 就交由给它进行处理,之后所有 catch 语句都不会再次执行。

      我们这就以 wiki 上的代码为例:每个人都有一个支出审批的额度,超过审批额度之后将会传递给下一个审批人,直到最后:
    审批人相关类

public abstract class PurchasePower {
    protected static final double BASE = 500;
    protected PurchasePower successor;

    abstract protected double getAllowable();
    abstract protected String getRole();

    public void setSuccessor(PurchasePower successor) {
        this.successor = successor;
    }

    public void processRequest(PurchaseRequest request){
        if (request.getAmount() < this.getAllowable()) {
            System.out.println(this.getRole() + " will approve $" + request.getAmount());
        } else if (successor != null) {
            successor.processRequest(request);
        }
    }
}
public class ManagerPPower extends PurchasePower {

    protected int getAllowable(){
        return BASE*10;
    }

    protected String getRole(){
        return "Manager";
    }
}

public class DirectorPPower extends PurchasePower {

    protected int getAllowable(){
        return BASE*20;
    }

    protected String getRole(){
        return "Director";
    }
}

public class VicePresidentPPower extends PurchasePower {

    protected int getAllowable(){
        return BASE*40;
    }

    protected String getRole(){
        return "Vice President";
    }
}

public class PresidentPPower extends PurchasePower {

    protected int getAllowable(){
        return BASE*60;
    }

    protected String getRole(){
        return "President";
    }
}

审批类

public class PurchaseRequest {
    private double amount;
    private String purpose;

    public PurchaseRequest(double amount, String purpose) {
        this.amount = amount;
        this.purpose = purpose;
    }

    public double getAmount() {
        return amount;
    }
    public void setAmount(double amt)  {
        amount = amt;
    }

    public String getPurpose() {
        return purpose;
    }
    public void setPurpose(String reason) {
        purpose = reason;
    }
}

最后是客户端的测试代码:

public class CheckAuthority {
    public static void main(String[] args) {
        ManagerPPower manager = new ManagerPPower();
        DirectorPPower director = new DirectorPPower();
        VicePresidentPPower vp = new VicePresidentPPower();
        PresidentPPower president = new PresidentPPower();
        manager.setSuccessor(director);
        director.setSuccessor(vp);
        vp.setSuccessor(president);

        // Press Ctrl+C to end.
        try {
            while (true) {
                System.out.println("Enter the amount to check who should approve your expenditure.");
                System.out.print(">");
                double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine());
                manager.processRequest(new PurchaseRequest(d, "General"));
           }
        } catch(Exception e) {
            System.exit(1);
        }
    }
}

代码简洁明了,都应该能看懂。

总结

  责任链模式的优点显而易见,可以对请求者和处理者关系解耦,提高代码的灵活性,通过改变链内的成员或调动他们的次序,允许你动态地新增或者删除职责;但是责任链模式最大的缺点在于对链中请求处理者的遍历,如果处理者太多那么必定会影响性能,特别是在一些递归调用中,而且不容易观察运行时的特征,有碍于除错。
  很多资料中会介绍纯和不纯的责任链模式,在标准的责任链模式中,责任链上的一个节点只允许有两个行为:处理或者推给下个节点处理,而不允许处理完之后又推给下个节点,前者被很多资料称为纯的责任链模式,而后者被称为不纯的责任链模式。其实在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。

源码下载

https://github.com/Jakey-jp/Design-Patterns/tree/master/ChainOfResponsibilityPattern

引用

https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
http://blog.csdn.net/jason0539/article/details/45091639

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android的MVC设计模式是一种软件架构模式,用于将应用程序的逻辑、数据和用户界面分离开来。它由三个主要组件组成:Model(模型)、View(视图)和Controller(控制器)。 1. Model(模型):模型负责处理应用程序的数据和业务逻辑。它包含数据的获取、存储和处理方法。在Android,模型通常是指数据源,例如数据库、网络请求或文件系统。 2. View(视图):视图负责展示数据给用户,并接收用户的输入。它通常是指Android的布局文件,例如XML文件,用于定义应用程序的用户界面。 3. Controller(控制器):控制器负责协调模型和视图之间的交互。它接收用户的输入,并根据输入更新模型和视图。在Android,控制器通常是指Activity或Fragment,它们处理用户的交互,并更新模型和视图。 MVC设计模式的优点是可以实现代码的重用和模块化,使得应用程序更易于维护和扩展。它将应用程序的不同部分分离开来,使得每个部分都可以独立开发和测试。 下面是一个简单的示例代码,演示了Android的MVC设计模式: ```java // Model public class UserModel { private String name; private int age; public UserModel(String name, int age) { this.name = name; this.age = age; } // Getters and setters // Controller public class UserController { private UserModel model; private UserView view; public UserController(UserModel model, UserView view) { this.model = model; this.view = view; } public void updateName(String name) { model.setName(name); } public void updateAge(int age) { model.setAge(age); } public void displayUser() { view.displayUser(model.getName(), model.getAge()); } } // View public class UserView { public void displayUser(String name, int age) { System.out.println("Name: " + name); System.out.println("Age: " + age); } } } // Usage UserModel model = new UserModel("John", 25); UserView view = new UserView(); UserController controller = new UserController(model, view); controller.displayUser(); // 输出:Name: John, Age: 25 controller.updateName("Mike"); controller.updateAge(30); controller.displayUser(); // 输出:Name: Mike, Age: 30 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值