策略模式
一、策略模式介绍
1、定义与类型
定义:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
可以替换掉大量的 if...else...…
类型:行为型
2、适用场景
系统有很多类,而他们的区别仅仅在于他们的行为
不同一个系统需要动态地在几种算法中选择一种
3、优点
符合开闭原则
避免使用多重条件转移语句
提高算法的保密性和安全性
4、缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
产生很多策略类
5、相关设计模式
策略模式和工厂模式(工厂方法和抽象工厂)
工厂模式接受指令创建对应的对象,策略模式接受创建好的对象执行不同的行为
策略模式和状态模式
二、代码示例
模拟场景:店铺针对不同的活动,调用不同的优惠策略
1、V1版本:
策略接口:
public interface PromotionStrategy {
void doPromotion();
}
策略实现类1(返现):
public class FanXianPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额存放到用户的余额中");
}
}
策略实现类2(立减):
public class LiJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("立减促销,商品的价格直接减去配置的价格");
}
}
策略实现类3(满减):
public class ManJianPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("满减促销,满200-20元");
}
}
策略调用类:
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void executePromotionStrategy(){
promotionStrategy.doPromotion();
}
}
测试类:
public class Test {
public static void main(String[] args) {
PromotionActivity promotionActivity618 = new PromotionActivity(new LiJianPromotionStrategy());
PromotionActivity promotionActivity1111 = new PromotionActivity(new FanXianPromotionStrategy());
promotionActivity618.executePromotionStrategy();
promotionActivity1111.executePromotionStrategy();
}
}
2、V2版本(结合简单工厂、静态容器单例模式):
策略接口与策略实现类一样,无需策略调用类,增加空策略类、策略工厂
空策略类:
public class EmptyPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("无促销活动");
}
}
策略工厂类:
public class PromotionStrategyFactory {
private static Map<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, PromotionStrategy>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.LIJIAN, new LiJianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN, new FanXianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN, new ManJianPromotionStrategy());
}
private PromotionStrategyFactory(){
}
// 无促销类
public static final EmptyPromotionStrategy NON_PROMOTION = new EmptyPromotionStrategy();
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
}
private interface PromotionKey{
String LIJIAN = "LIJIAN";
String FANXIAN = "FANXIAN";
String MANJIAN = "MANJIAN";
}
}
测试类:
public class Test {
public static void main(String[] args) {
String promotionKey = "LIJIAN";
PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
promotionStrategy.doPromotion();
}
}
三、源码示例
1、JDK中的Comparator
在ArrayList的sort方法中,需要传入一个Comparator,作为排序的策略