设计模式(十二)责任链模式

引子

今天来看看什么是责任链模式。责任链,从字面意思可以看出,不同的责任连起来,成为一条责任链,针对不同的情况,在这条链上寻找对应的处理办法。

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

责任链模式的重点是在“链”上,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果。

以下是通用类图:

在生活场景中,银行会针对存入不同的货币做出不同的处理,以下我们就用这个例子来说明责任链的使用方式。

抽象处理者

public abstract class BankHandler {
    //不同的货币
    public final static int RMB_LEVEL_REQUEST = 1;
    public final static int USD_LEVEL_REQUEST = 2;
    public final static int EUR_LEVEL_REQUEST = 3;
    public final static int JPY_LEVEL_REQUEST = 4;

    //能处理的级别
    private int level = 0;

    //责任传递,下一个责任处理是谁
    private BankHandler nextHandler;

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

    //某一种货币(人民币、美元、欧元、日元)要求存入银行,要处理这个请求
    public final void HandleMessage(IMoney money) {
        if (money.getType() == this.level) {
            this.response(money);
        } else {
            if (this.nextHandler != null) {
                this.nextHandler.HandleMessage(money);
            } else {
                System.out.println("*******************************");
                System.out.println("---处理不了的货币,按不处理对待!---");
                System.out.println("*******************************");
            }
        }
    }

    //如果处理不了这个,告知下一个处理人
    public void setNext(BankHandler handler) {
        this.nextHandler = handler;
    }

    //有请求当然要回应
    protected abstract void response(IMoney money);
}

具体处理者

public class RMB extends BankHandler {
    public RMB() {
        super(BankHandler.RMB_LEVEL_REQUEST);
    }

    @Override
    protected void response(IMoney money) {
        System.out.println("---我存RMB,帮我存入人民币账户---");
        System.out.println(money.getRequest());
        System.out.println("RMB处理完成,账户余额:¥66666");
    }
}
public class USD extends BankHandler {
    public USD() {
        super(BankHandler.USD_LEVEL_REQUEST);
    }

    @Override
    protected void response(IMoney money) {
        System.out.println("---我存USD,帮我存入美元账户---");
        System.out.println(money.getRequest());
        System.out.println("USD处理完成,账户余额 :$88888");
    }
}
public class EUR extends BankHandler {
    public EUR() {
        super(BankHandler.EUR_LEVEL_REQUEST);
    }
    @Override
    protected void response(IMoney money) {
        System.out.println("---我存EUR,帮我存入欧元账户---");
        System.out.println(money.getRequest());
        System.out.println("EUR处理完成,账户余额: €77777");
    }
}
public class JPY extends BankHandler {
    public JPY() {
        super(BankHandler.JPY_LEVEL_REQUEST);
    }
    @Override
    protected void response(IMoney money) {
        System.out.println("---我存JPY,帮我存入日元账户---");
        System.out.println(money.getRequest());
        System.out.println("JPY处理完成,账户余额:円55555");
    }
}

货币类

public class Money implements IMoney{
    /*
        通过一个int类型参数来描述货币的类型
        1:人民币
        2:美元
        3:欧元
        4:日元
     */
    private int type = 0;
    //货币的处理请求
    private String request = "";

    //构造函数传递过来请求
    public Money(int type, String request) {
        this.type = type;
        //为了便于显示,在这里做了点处理
        switch (this.type) {
            case 1:
                this.request = "人民币请求是:" + request;
                break;
            case 2:
                this.request = "美元请求是:" + request;
                break;
            case 3:
                this.request = "欧元请求是:" + request;
                break;
            case 4:
                this.request = "日元请求是:" + request;
        }
    }

    //获得货币的类型
    public int getType() {
        return type;
    }

    //获得货币的处理请求
    public String getRequest() {
        return request;
    }
}

货币接口

public interface IMoney {
    //获得货币类型
    int getType();

    //获得货币处理请求
    String getRequest();
}

测试类

public class Client {
    public static void main(String[] args) {
        //随机生成几种货币类型
        Random random = new Random();
        ArrayList<IMoney> arrayList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            arrayList.add(new Money(random.nextInt(5), "我想存钱"));
        }
        //定义四个请示对象
        BankHandler rmb = new RMB();
        BankHandler usd = new USD();
        BankHandler eur = new EUR();
        BankHandler jpy = new JPY();
        //设置处理顺序
        rmb.setNext(usd);
        usd.setNext(eur);
        eur.setNext(jpy);
        for (IMoney m : arrayList) {
            rmb.HandleMessage(m);
        }
    }
}

测试结果

责任链的优点

责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。

责任链的缺点

  • 性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候。
  • 调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试逻辑更复杂。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值