设计模式——责任链模式

设计模式——责任链模式

Posted by 不学无数 on April 22, 2019

设计模式——责任链模式

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

从字面意思可以理解,责任链模式重点在上。只要符合相应的处理逻辑的就进去处理,不然一直传递下去。

责任链模式

所以我们可以得出责任链的通用类图。重点在于每一个链节点的表示。所以需要先抽象出来一个链节点。

责任链模式类图

其实在程序设计中也有这种情况,例如我们在系统中收到这样的一个需求,对于金额进行换算,由于一开始的时候没有想到有那么多币种,所以只针对于人民币进行了结算,但是随后由于国际化的业务。来了许多币种的,这时候就可以用责任链模式进行补救。

首先定义抽象的处理器

abstract class MoneyHandler{
	 //币种
    private String currency;
    private MoneyHandler moneyHandler = null;

    public MoneyHandler(String currency){
        this.currency = currency;
    }

    public final void handlerRequest(Money money){
    	 //是否停留在此链点的标准,不符合就进入下一个链点
        if (currency.equals(money.getCurrency())){
            invoke(money);
        }else {
            if (getNext()!=null){
                getNext().handlerRequest(money);
            }else {
                System.out.println("未知币种:"+money.getCurrency());
            }
        }
    }

    public MoneyHandler getNext(){
        return this.moneyHandler;
    }

    public MoneyHandler setNext(MoneyHandler moneyHandler){
        this.moneyHandler = moneyHandler;
        return moneyHandler;
    }

   public abstract void invoke(Money money);
}

两个币种的处理器人民币和美元的


class CNYMoneyHandler extends MoneyHandler {

    public CNYMoneyHandler(String currency) {
        super(currency);
    }

    @Override
    public void invoke(Money money) {
        System.out.println("人民币处理");
    }
}

class USDMoneyHandler extends MoneyHandler {

    public USDMoneyHandler(String currency) {
        super(currency);
    }

    @Override
    public void invoke(Money money) {
        System.out.println("美元处理");
    }
}

class Money{
    private String currency;
    private BigDecimal amount;
}

此时进行如下调用就能走到相应的处理链节点了

        MoneyHandler cny = new CNYMoneyHandler("CNY");
        MoneyHandler usd = new USDMoneyHandler("USD");
        Money cnyMoney = new Money("CNY",new BigDecimal("100"));
        Money usdMoney = new Money("USD",new BigDecimal("100"));
        Money noMoney = new Money("BBBBBBB",new BigDecimal("100"));
        //设置链的下一个节点
        cny.setNext(usd);
        cny.handlerRequest(cnyMoney);
        cny.handlerRequest(usdMoney);
        cny.handlerRequest(noMoney);

输出如下

人民币处理
美元处理
未知币种:BBBBBBB