策略模式介绍
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户,比如公司都会为我们每个人交公积金,但是每个公司所交的比例又不一样,又如我们每个每个人出行所选择的交通工具也不一样,有人开劳斯莱斯出行,有人开宾利,而我要么坐地铁,要么骑共享单车
例子解说
上一篇讲了用适配器模式来接入第三方外卖平台,实现数据的统一管理,今天我们用策略模式来设计餐饮系统的优惠政策,我们的餐饮系统肯定会时不时的做优惠政策,比如节假日,会员生日等,会做一些折扣和减免,现在系统里面主要有三种优惠和折扣类型,分别是生日折扣,方案折扣,优惠卷,它们的都有自己相应的优惠政策,下面我们用策略模式来进行设计。
伪代码实现
定义一个订单优惠策略接口,里面有一个折扣方法,我们为接口添加了泛型,接口方法需要传入优惠类型和订单总金额。
代码语言: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.系统的扩展性好,耦合度低。
策略模式缺点
策略模式中如果策略类变得很多,将会增加系统的复杂度
今天的分享就到这里,感谢你的观看,我们下期见。