前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >白话设计模式之策略模式

白话设计模式之策略模式

作者头像
小四的技术之旅
发布2022-07-26 16:58:55
3480
发布2022-07-26 16:58:55
举报
文章被收录于专栏:小四的技术文章

策略模式介绍

该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户,比如公司都会为我们每个人交公积金,但是每个公司所交的比例又不一样,又如我们每个每个人出行所选择的交通工具也不一样,有人开劳斯莱斯出行,有人开宾利,而我要么坐地铁,要么骑共享单车

例子解说

上一篇讲了用适配器模式来接入第三方外卖平台,实现数据的统一管理,今天我们用策略模式来设计餐饮系统的优惠政策,我们的餐饮系统肯定会时不时的做优惠政策,比如节假日,会员生日等,会做一些折扣和减免,现在系统里面主要有三种优惠和折扣类型,分别是生日折扣,方案折扣,优惠卷,它们的都有自己相应的优惠政策,下面我们用策略模式来进行设计。

伪代码实现

定义一个订单优惠策略接口,里面有一个折扣方法,我们为接口添加了泛型,接口方法需要传入优惠类型和订单总金额。

代码语言:javascript
复制
public interface IOrderDiscountStrategy<T> {
      BigDecimal discount(T t , BigDecimal totalMoney);
}

编写相应的优惠策略实现类

1.生日折扣实现类

代码语言:javascript
复制
public class BirthdayDiscountStrategy implements IOrderDiscountStrategy<Member>{
      @Override
      public BigDecimal discount(Member member , BigDecimal totalMoney) {
          return totalMoney.multiply(member.getDiscount());
      }
}

2.优惠卷减免实现类

代码语言:javascript
复制
public class CouponDiscountStrategy implements IOrderDiscountStrategy<Coupon>{
      @Override
      public BigDecimal discount(Coupon coupon , BigDecimal totalMoney) {
          return totalMoney.subtract(coupon.getMoney());
      }
}

3.方案折扣实现类

代码语言:javascript
复制
public class DiscountSchemeStrategy implements IOrderDiscountStrategy<DiscountScheme> {
      @Override
      public BigDecimal discount(DiscountScheme discountScheme , BigDecimal totalMoney) {
          return totalMoney.multiply(discountScheme.getDiscount());
      }
}

创建订单折扣上下文类OrderDiscountContext

代码语言:javascript
复制
public class OrderDiscountContext<T> {
    IOrderDiscountStrategy<T> orderDiscountStrategy;
    public OrderDiscountContext(IOrderDiscountStrategy<T> orderDiscountStrategy){
        this.orderDiscountStrategy = orderDiscountStrategy;
    }
    public BigDecimal discount(T t , BigDecimal totalMoney){
        return this.orderDiscountStrategy.discount(t,totalMoney);
    }
}

测试调用

代码语言:javascript
复制
    public static void main(String[] args) {
        Member member = new Member("123456", "steak", new Date(), new BigDecimal("0.7"));
        IOrderDiscountStrategy<Member> birthdayStrategy = new BirthdayDiscountStrategy();
        BigDecimal birthday = birthdayStrategy.discount(member, new BigDecimal(584));
        System.out.println("生日优惠价:"+birthday);

        Coupon coupon = new Coupon("88888", new BigDecimal("121.5"), "开业优惠券");
        IOrderDiscountStrategy<Coupon> couponDiscountStrategy = new CouponDiscountStrategy();
        BigDecimal couponDiscount = couponDiscountStrategy.discount(coupon, new BigDecimal(584));
        System.out.println("优惠卷优惠价:"+couponDiscount);

        DiscountScheme discountScheme = new DiscountScheme("23423423", new BigDecimal("0.7"), "七夕优惠");
        IOrderDiscountStrategy<DiscountScheme> discountSchemeIOrderDiscountStrategy = new DiscountSchemeStrategy();
        BigDecimal discount = discountSchemeIOrderDiscountStrategy.discount(discountScheme, new BigDecimal(1259));
        System.out.println("七夕优惠价:"+discount);
    }
}
    输出:
      生日优惠价:408.8
      优惠卷优惠价:462.5
      七夕优惠价:881.3

由上可知,订单有多种优惠策略,我们只需要定义相应的优惠策略算法,便可以计算出相应的优惠后的金额,如果不适用策略模式的话,我们很大概率会写出如下代码,这样,代码里面就会充斥着大量的if/else语句,随着需求的不断增多,将会越来越复杂,不利于维护。

代码语言:javascript
复制
public class OrderService{
    public void discount(String type , BigDecimal totalMoney) {
        if ("会员生日".equals(type)){
            discount(totalMoney);
        }else if ("折扣方案".equals(type)){
            discount(totalMoney);
        }else if ("优惠卷".equals(type)){
            discount(totalMoney);
        }
    }
}

策略模式应用场景

1.一个系统中有多个类,它们之间的区别仅在于它们的行为不同,那么使用策略模式可以动态的选择一种行为。

2.对于某一种行为,避免大量的判断,使用策略模式是很好的选择。

策略模式优点

1.可以灵活的切换算法,避免大量的判断 2.系统的扩展性好,耦合度低。

策略模式缺点

策略模式中如果策略类变得很多,将会增加系统的复杂度

今天的分享就到这里,感谢你的观看,我们下期见。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 刘牌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档