文章目录
1. 定义
策略模式: 指定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式上算法的变化不会影响到使用算法的用户
可以避免多重分支的if...esle
和switch
语句
2. 适用场景
Spring中以Strategy结尾的类都是策略模式的体现
3. 代码实现
- 通过工厂模式 + 单例模式 + 策略模式的方式实现
- 后面增加策略只需要增加对应的具体策略, 在策略枚举中增加对应的策略名称, 在工厂中增加对应的策略就能完成策略活动的增加, 不需要修改过多的代码, 对于用户而言是无感知的
3.1 策略抽象类
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
public interface PromotionStrategy {
/**
* 优惠活动
*/
void doPromotion();
}
3.2 具体策略
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
/**
* 返现活动
*/
public class CashBackStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("正在执行返现活动");
}
}
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
/**
* 优惠券活动
*/
public class CouponStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("领取优惠券,正在执行优惠券活动");
}
}
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
/**
* 无促销活动
*/
public class EmptyStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("无促销活动");
}
}
3.3 策略枚举
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
public enum PromotionEnum {
/**
* 返现
*/
CASHBACK,
/**
* 优惠券
*/
COUPON,
/**
* 无活动
*/
EMPTY
}
3.4 策略工厂
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
/**
* 工厂模式 + 单例模式
*/
public class PromotionStrategyFactory {
private static Map<Enum, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionEnum.CASHBACK, new CashBackStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionEnum.COUPON, new CouponStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionEnum.EMPTY, new EmptyStrategy());
}
private PromotionStrategyFactory() {}
public static PromotionStrategy getPromotionStrategy (PromotionEnum promotionEnum) {
return PROMOTION_STRATEGY_MAP.get(promotionEnum);
}
}
3.5 测试类
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;
public class PromotionStrategyTest {
public static void main(String[] args) {
PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(PromotionEnum.CASHBACK);
promotionStrategy.doPromotion();
}
}
4. 源码分析
4.1 Arrays中的parallelSort
在Arrays中parallelSort是用来排序的,其中存在一个方法是可以自定义排序策略的,用户可以自己实现Comparator定义自己的排序策略
public class Arrays {
public static <T> void parallelSort(T[] a, Comparator<? super T> cmp) {
if (cmp == null)
cmp = NaturalOrder.INSTANCE;
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, 0, n, cmp, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<T>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, cmp).invoke();
}
}
4.2 Spring中Resource
Spring的Resource类的实现类就是策略模式的体现
5. 优缺点
5.1 优点
- 策略模式符合开闭原则
- 避免使用多重条件转移语句,如if…else语句,switch语句
- 使用策略模式可以提高算法的保密性和安全性
5.2 缺点
- 客户端必须知道所有的策略,并且自行决定使用哪一个策略
- 代码中会产生非常多策略类,增加维护难度