设计模式系列:责任链模式

引入

1.案例

2.面向实现编程方案

首先来看一段代码:

 public void test(int i, Request request){
        if(i==1){
            Handler1.response(request);
        }else if(i == 2){
            Handler2.response(request);
        }else if(i == 3){
            Handler3.response(request);
        }else if(i == 4){
            Handler4.response(request);
        }else{
            Handler5.response(request);
        }
    }

  代码的业务逻辑是这样的,方法有两个参数:整数i和一个请求request,根据i的值来决定由谁来处理request,如果i==1,由Handler1来处理,如果i==2,由Handler2来处理,以此类推。在编程中,这种处理业务的方法非常常见,所有处理请求的类有if…else…条件判断语句连成一条责任链来对请求进行处理,相信大家都经常用到。这种方法的优点是非常直观,简单明了,并且比较容易维护,但是这种方法也存在着几个比较令人头疼的问题:

• 代码臃肿:实际应用中的判定条件通常不是这么简单地判断是否为1或者是否为2,也许需要复杂的计算,也许需要查询数据库等等,这就会有很多额外的代码,如果判断条件再比较多,那么这个if…else…语句基本上就没法看了。

• 耦合度高:如果我们想继续添加处理请求的类,那么就要继续添加else if判定条件;另外,这个条件判定的顺序也是写死的,如果想改变顺序,那么也只能修改这个条件语句。

  既然缺点我们已经清楚了,就要想办法来解决。这个场景的业务逻辑很简单:如果满足条件1,则由Handler1来处理,不满足则向下传递;如果满足条件2,则由Handler2来处理,不满足则继续向下传递,以此类推,直到条件结束。其实改进的方法也很简单,就是把判定条件的部分放到处理类中,这就是责任连模式的原理。

3.面向设计编程方案

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

一.名称

二.问题(为了解决什么问题)

  就像开始的例子那样,假如使用if…else…语句来组织一个责任链时感到力不从心,代码看上去很糟糕时,就可以使用责任链模式来进行重构。

三.解决方案(主要体现在uml和核心代码上)

责任链模式:避免将请求发送者与接受者耦合在一起,让多个对象都有机会接受请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。

责任链模式体现了:开闭原则、依赖倒置原则、里氏替换原则。
因为使用了抽象类——开闭原则
因为使用了抽象类——里氏替换原则
因为使用了抽象类和继承——依赖倒置原则

这里写图片描述

四.例子

古代三从四德的例子:在家从父,出嫁从夫,夫死从子
请求

/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public interface IWomen {
    public int getType();
    public String getRequst();
}
/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public class Women implements IWomen {
    /*
    * 通过一个int类型的参数来描述妇女的个人状况
    * 1.未出嫁
    * 2.出嫁
    * 3.夫死
     */

    private int type = 0;
    private String request = "";

    public Women(int type, String request) {
        this.type = type;
        switch (type) {
            case 1:
                this.request = "女儿的请求是:" + request;
                break;
            case 2:
                this.request = "妻子的请求是:" + request;
                break;
            case 3:
                this.request = "母亲的请求是:" + request;
                 break;
        }
    }

    @Override
    public int getType() {
        return this.type;
    }

    @Override
    public String getRequst() {
        return this.request;
    }
}

处理

/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public abstract class Handler {
    // 父亲
    public final static int FATHER_LEVEL_REQUEST = 1;
    // 丈夫
    public final static int HUSRAND_LEVEL_REQUEST = 2;
    // 儿子
    public final static int SON_LEVEL_REQUEST = 3;
    // 能处理的等级
    private int level = 0;

    // 下一个责任人
    private Handler nextHandler;

    public Handler(int level) {
        this.level = level;
    }

    /**
     *
     * @param handler
     */
    public void setNext(Handler handler) {
        this.nextHandler = handler;
    }

    /**
     * 对请示的回应
     * @param women
     */
    protected abstract void response(IWomen women);

    /**
     * 处理请求
     * @param women
     */
    public final void HandleMessage(IWomen women) {
        if (women.getType() == this.level) {
            this.response(women);
        } else {
            if (this.nextHandler != null) {
                this.nextHandler.HandleMessage(women);
            } else {
                System.out.println("------没地方请示了,按不同意处理-----");
            }
        }
    }
}
/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public class Son extends Handler {
    public Son() {
        super(Handler.SON_LEVEL_REQUEST);
    }

    @Override
    protected void response(IWomen women) {
        System.out.println("儿子处理了请求");
    }
}

/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public class Husband extends Handler{

    public Husband() {
        super(Handler.HUSRAND_LEVEL_REQUEST);
    }

    @Override
    protected void response(IWomen women) {
        System.out.println("丈夫处理了请求");
    }
}
/**
 * Created by annuoaichengzhang on 16/3/23.
 */
public class Father extends Handler {

    public Father() {
        super(Handler.FATHER_LEVEL_REQUEST);
    }

    @Override
    protected void response(IWomen women) {
        System.out.println("父亲答复");
    }
}

client


import java.util.ArrayList;
import java.util.Random;

/**
 * Created by annuoaichengzhang on 16/3/23.
 * 三从四德的例子:在家从父,出嫁从夫,夫死从子
 */
public class Client {
    public static void main(String[] args) {
        Random random = new Random();
        ArrayList<IWomen> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new Women(random.nextInt(4), "我要出去逛街"));
        }
        Handler father = new Father();
        Handler husband = new Husband();
        Handler son = new Son();
        father.setNext(husband);
        husband.setNext(son);
        for (IWomen women : list) {
            father.HandleMessage(women);
        }
    }
}

五.效果(有啥优缺点)

  责任链模式与if…else…相比,他的耦合性要低一些,因为它把条件判定都分散到了各个处理类中,并且这些处理类的优先处理顺序可以随意设定。责任链模式也有缺点,这与if…else…语句的缺点是一样的,那就是在找到正确的处理类之前,所有的判定条件都要被执行一遍,当责任链比较长时,性能问题比较严重。

  责任链模式其实就是一个灵活版的if…else…语句,它就是将这些判定条件的语句放到了各个处理类中,这样做的优点是比较灵活了,但同样也带来了风险,比如设置处理类前后关系时,一定要特别仔细,搞对处理类前后逻辑的条件判断关系,并且注意不要在链中出现循环引用的问题。

这里写图片描述

常见案例

采购单的分级审批

假条审批模块

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值