java设计模式-责任链模式

责任链模式

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

责任链模式-当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式(Chain of Responsibility Pattern)

模式和结构定义

在这里插入图片描述

  • Client:客户端,请求的发起者
  • Handler:抽象处理者,声明一个请求方法,并在其中保持一个对下一个处理节点Handler对象的引用
  • ConcreteHandler:具体处理角色,对请求进行处理;如果不能处理则将请求转发给下一个节点对象处理

应用实例

双十一活动,购买商品时,有很多优惠券活动,其中就包括满减券和折扣券。下面用责任链模式来实现一个使用优惠券购买商品的实例

定义优惠券业务逻辑接口

/**
 * 优惠券业务逻辑接口
 *
 * @author shengyong.huang
 * @date 2020-07-21
 */
public interface UseCouponBase {
    /**
     * 所有处理逻辑的方法
     *
     * @param couponList    责任链集合
     * @param useCouponBase 自身对象
     * @param discounts     折扣 3折/5折 0.3/0.5
     */
    void doSomething(List couponList, UseCouponBase useCouponBase, BigDecimal discounts);

}

优惠券业务控制路由

/**
 * 优惠券路由
 *
 * @author shengyong.huang
 * @date 2020-07-21
 */

public class UseCouponChain implements UseCouponBase {
    // 所有 case 列表
    private List<UseCouponBase> mCaseList = new ArrayList<>();
    // 索引,用于遍历所有 case 列表
    private int index = 0;

    // 添加 case
    public UseCouponChain addBaseCase(UseCouponBase base) {
        mCaseList.add(base);
        return this;
    }

    @Override
    public void doSomething(List couponList, UseCouponBase useCouponBase, BigDecimal discounts) {
        //所有遍历完了,直接返回
        if (index == mCaseList.size()) {
            return;
        }
        //获取当前 case
        UseCouponBase currentCase = mCaseList.get(index);
        //修改索引值,以便下次回调获取下个节点,达到遍历效果
        index++;
        //调用 当前 case 处理方法
        currentCase.doSomething(couponList, useCouponBase, discounts);
    }
}

折扣券责任链处理

/**
 * 折扣券处理
 *
 * @author shengyong.huang
 * @date 2020-07-21
 */
public class DiscountChain implements UseCouponBase {
    @Override
    public void doSomething(List couponList, UseCouponBase useCouponBase, BigDecimal discounts) {

        System.out.println("使用折扣券逻辑处理");
        //使用折扣券逻辑处理(怎么使用的代码此处我就省略了,具体业务逻辑具体实现就行)

        //交给下一个执行器处理
        useCouponBase.doSomething(couponList, useCouponBase, discounts);
    }
}

满减券责任链处理

/**
 * 满减券处理
 *
 * @author shengyong.huang
 * @date 2020-07-21
 */
public class MoneyOffChain implements UseCouponBase {
    @Override
    public void doSomething(List couponList, UseCouponBase useCouponBase, BigDecimal discounts) {

        System.out.println("使用满减券逻辑处理");
        //使用满减券逻辑处理(怎么使用的代码此处我就省略了,具体业务逻辑具体实现就行)

        //交给下一个处理
        useCouponBase.doSomething(couponList, useCouponBase, discounts);
    }
}

测试方法

/**
 * 测试方法
 *
 * @author shengyong.huang
 * @date 2020-07-21
 */
public class TestMain {

    public static void main(String[] args) {
        //新建一个各类优惠券处理路由
        UseCouponChain useCouponChain = new UseCouponChain();
        //需要处理哪些优惠券按顺序添加进路由就行
        useCouponChain.addBaseCase(new MoneyOffChain())
                .addBaseCase(new DiscountChain());
        /*这里couponList 是形参,
        具体业务中可以是用户的可用优惠券列表,
        可以传入执行器中进行业务逻辑处理*/
        List couponList = new ArrayList<>();
        //执行业务逻辑处理
        useCouponChain.doSomething(couponList, useCouponChain, new BigDecimal(0));
    }

}

运行结果

使用满减券逻辑处理
使用折扣券逻辑处理

优点和不足

优点:

  • **请求者和接受者松散耦合,以及能动态组合职责。**弱化了发出请求的人和处理请求的人之间的关系。发出请求的人只需要向第一个具体的处理者发送请求,然后就可以不用管了,处理者会在责任链上自己寻找处理的方法。这样就解耦了处理者和请求者之间的关系。
  • 可以动态的改变责任链。责任链还有的好处就是可以动态的改变责任,删除或者添加或者改变顺序。
  • 让各个处理者专注于实现自己的职责。责任链模式同时还做到了处理者之间的解耦,处理者自己专注于自己的处理逻辑就好,不管其他处理者干什么。

缺点:

  • 不能保证请求一定被接收。
  • 可能不容易观察运行时的特征,有碍于除错
  • **推卸责任也可能导致处理延迟。系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。**我们可以责任链模式需要在责任链上传播责任,直至找到合适的处理对象。这样提高了程序的灵活性,但同时也出现了处理的延迟,因为有一个寻找的过程。所以需要低延迟的情况下,就不应该使用责任链模式

使用场景

  • 比如jsp servlet 的 Filter
  • 有许多对象可以处理用户的请求,希望程序在运行期间自动确定处理用户的那个对象。
  • 希望用户不必明确指定接受者的情况下,向多个接受者的一个提交请求。
  • 程序希望动态制定可处理用户请求的对象集合。

补充

参考:
设计模式之责任链模式(Chain of Responsibility)
设计模式学习笔记之六:责任链模式
设计模式学习笔记(六:责任链模式)
12、责任链模式(设计模式笔记)
优惠券使用—责任链模式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值