一、简单介绍
策略这个词应该怎么理解,打个比方说,我们出门的时候会选择不同的出行方式,比如骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。
再比如我们去逛商场,商场现在正在搞活动,有打折的、有满减的、有返利的等等,其实不管商场如何进行促销,说到底都是一些算法,这些算法本身只是一种策略,并且这些算法是随时都可能互相替换的,比如针对同一件商品,今天打八折、明天满100减30,这些策略间是可以互换的。
有很多时候我们会使用if else 来解决这个问题
if(type.equals("A")){
// do func A
}else if(type.equals("B")){
// do func B
}else if(type.equals("C")){
// do func C
}else[
//...
}
这种 if-else 或者 switch-case 代码在每个分支都会判断分支类型,然后执行不同的方法获取结果,当代码分支比较少并且确定不会增加时,使用这种方式也是完全 ok 的,但是当分支比较多,并且后面可能会增加分支判断条件时,这种方式就违反了单一职责和开闭原则,因此对于我们开发工作中遇到这种情况,就是自然的考虑能不能用策略模式去重写,将代码和业务逻辑解耦,这样才有利于后续的维护工作。
比如,上面的if-else 我们可以优化为下面的代码
策略抽象接口
public interface IStrategy {
void doSomething();
}
策略A
public class StrategyA implements IStrategy {
@Override
public void doSomething() {
System.out.println("A");
}
}
策略B
public class StrategyB implements IStrategy {
@Override
public void doSomething() {
System.out.println("B");
}
}
策略C
public class StrategyC implements IStrategy {
@Override
public void doSomething() {
System.out.println("C");
}
}
工厂
public class SimpleStrategyFactory {
public static final String STRATEGY_A = "A";
public static final String STRATEGY_B = "B";
public static final String STRATEGY_C = "C";
public static final String STRATEGY_DUFAULT = "A";
private static Map<String, IStrategy> StrategyMap = new ConcurrentHashMap<>();
static {
StrategyMap.put(STRATEGY_A,new StrategyA());
StrategyMap.put(STRATEGY_B,new StrategyB());
StrategyMap.put(STRATEGY_C,new StrategyC());
}
public static IStrategy get(String key){
if(!StrategyMap.containsKey(key)){
return StrategyMap.get(STRATEGY_DUFAULT);
}
return StrategyMap.get(key);
}
}
测试类
public class StrategyTest {
public static void main(String[] args) {
IStrategy strategy = SimpleStrategyFactory.get("A");
strategy.doSomething();
}
}
类结构图
场景二:商场促销活动
促销策略接口 IStrategy
public interface IStrategy {
void discount();
}
返现策略类
public class CashbackStrategy implements IStrategy {
public void discount() {
System.out.println("返现促销");
}
}
优惠券策略类
public class CouponStrategy implements IStrategy {
public void discount() {
System.out.println("商品的价格直接减优惠券面值抵扣");
}
}
无优惠的策略类
public class EmptyStrategy implements IStrategy {
public void discount() {
System.out.println("无促销活动");
}
}
满减策略类
public class FullMinusStrategy implements IStrategy {
public void discount() {
System.out.println("满500,减100活动");
}
}
策略工厂类
public class PromotionStrategyFactory {
private static Map<String, IStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, IStrategy>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.FULLMINUS,new FullMinusStrategy());
}
private static final IStrategy NON_PROMOTION = new EmptyStrategy();
private PromotionStrategyFactory(){}
public static IStrategy getPromotionStrategy(String promotionKey){
IStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
}
private interface PromotionKey{
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String FULLMINUS = "FULLMINUS";
}
}
测试类
public class StrategyTest {
public static void main(String[] args) {
IStrategy strategy = PromotionStrategyFactory.getPromotionStrategy("FULLMINUS");
strategy.discount();
}
}