策略模式简介:
策略模式对应于解决某一个问题的一个算法族(多个算法),允许用户从该算法族中任选一种算法解决某一问题;同时,可以方便的更换算法或用户自定义新的算法;并且由用户决定调用最终使用哪个算法。
应用场景如下:
模拟商场购物场景,不同会员等级的客户会有不同的打折策略。具体代码如下:
public class Strategy {/*** 根据不同的用户对商品打折* @param price* @return*/public BigDecimal discounted(VipLevel vipLevel,BigDecimal price){switch (vipLevel){case PT:return price.multiply(new BigDecimal(0.6));case GOLD:return price.multiply(new BigDecimal(0.7));case SILVER:return price.multiply(new BigDecimal(0.8));case COPPER:return price.multiply(new BigDecimal(0.9));default:return null;}}}
枚举类,定义会员等级
/*** 会员等级*/public enum VipLevel {PT("pt"),GOLD("gold"),SILVER("silver"),COPPER("copper");String level;VipLevel(String level) {this.level = level;}}
虽然有点样子了,但这种实现方式肯定不是我们最终想要的,原因有以下三点:
1.每次新增算法都要改这个类,违反开闭原则;
2.策略多了非常不好维护;
3.业务和策略耦合在一起
所以我们来将其改造成真正的策略模式:
我们先定义一个策略接口:
该方法就是说,传进来一个原价格,我根据具体的实现返回给一个打折后的价格。
public interface Strategy {BigDecimal discounted(BigDecimal price);}

image.png
编写几个实现:
黄金会员
public class GoldStrategy implements Strategy {@Overridepublic BigDecimal discounted(BigDecimal price) {return price.multiply(new BigDecimal(0.7));}}
青铜会员
public class CopperStrategy implements Strategy {@Overridepublic BigDecimal discounted(BigDecimal price) {return price.multiply(new BigDecimal(0.9));}}
既然销售策略有了,现在我们再定义一个销售职员接口:
销售人员只关注价格,不关注算法。
/*** 销售员接口**/public interface Saler {BigDecimal coculate(BigDecimal price);}
定义一个抽象类,继承这个抽象类的子类都需要带有一个策略,白话就是说这一类的销售人员都需要使用实现了Strategy接口的策略去计算价格。
public abstract class ProductionSaler implements Saler{protected Strategy strategy;public ProductionSaler(Strategy strategy) {this.strategy = strategy;}}
具体的销售人员:
public class RealSaler extends ProductionSaler{public RealSaler(Strategy strategy) {super(strategy);}@Overridepublic BigDecimal coculate(BigDecimal price) {return strategy.discounted(price);}}
测试类:
public class Test {public static void main(String[] args) {Saler saler = new RealSaler(new CopperStrategy());System.out.println(saler.coculate(new BigDecimal(60)));}}

