白话设计模式之策略模式

2022-07-26 16:58:55 浏览数 (1)

策略模式介绍

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

例子解说

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

伪代码实现

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

代码语言: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.系统的扩展性好,耦合度低。

策略模式缺点

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

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

0 人点赞