定义
定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
if…else…
类型
行为型
适用场景
①、系统有很多类,而它们的区别仅仅在于它们的行为不同。
②、一个系统需要动态地在几种算法中选择一种。
优缺点
优点:
①、开闭原则
②、避免使用多重条件转移语句
③、提高算法的保密性和安全性
缺点:
①、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
②、 产生很多策略类
代码实现
案例:电商网站经常会在不同的节日搞不同的促销活动,例如:满减、立减、返现等等。根据这个场景来使用策略模式实现。
首先创建一个促销策略的接口
public interface PromotionStrategy {
/**
* 促销
*/
void doPromotion();
}
然后,分别创建不同促销策略的实现类。
返现促销
public class FanXianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额存放到用户的余额中");
}
}
立减促销
public class LiJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("立减促销,课程的价格直接减去配置的价格");
}
}
满减促销
public class ManJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("满减促销,满100减50");
}
}
无促销活动
public class EmptyPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("无促销策略");
}
}
促销策略有了,还需要创建具体的促销活动
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute() {
promotionStrategy.doPromotion();
}
}
创建测试类
public class MainTest {
public static void main(String[] args) {
PromotionActivity promotionActivity = null;
// 前台传过来的标志
String PromotionKey = "LiJian";
if (StringUtils.equals(PromotionKey, "LiJian")) {
// 京东618立减
promotionActivity = new PromotionActivity(new LiJianPromotionStrategy());
} else if (StringUtils.equals(PromotionKey, "ManJian")) {
// 双11 满减
promotionActivity = new PromotionActivity(new ManJianPromotionStrategy());
} else {
promotionActivity = new PromotionActivity(new EmptyPromotionStrategy());
}
promotionActivity.execute();
}
}
输出结果:
C:\android\java\jdk1.8\bin\java.exe
立减促销,课程的价格直接减去配置的价格
基本上策略模式就实现了,但是查看上面的代码,在开放立减策略或者其他策略的时候,都需要重新new一个当前的策略,这并不是我们所需要的。为了消除if…else…以及避免多次重复的创建对象,结合工厂设计模式对当前的代码进行改进。
首先创建一个策略工厂
public class PromotionStrategyFactory {
/**
* 存放所有促销策略
*/
private static final Map<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
/**
* 没有促销
*/
private static final EmptyPromotionStrategy EMPTY_PROMOTION_STRATEGY = new EmptyPromotionStrategy();
private interface PromotionKey {
String LIJian = "LiJian";
String FanXian = "FanXian";
String ManJian = "ManJian";
}
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.FanXian, new FanXianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.LIJian, new LiJianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.ManJian, new ManJianPromotionStrategy());
}
private PromotionStrategyFactory() {
}
public static PromotionStrategy getPromotionStrategy(String PromotionKey) {
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(PromotionKey);
return promotionStrategy == null ? EMPTY_PROMOTION_STRATEGY : promotionStrategy;
}
}
这里使用Map来存放所有的促销策略,并在应用初始化时,就将策略放入Map集合中,并提供获取策略的方法。
编写测试类
@Test
public void testMethod2(){
// 前台传过来的标志
String PromotionKey = "ManJian";
PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(PromotionKey));
promotionActivity.execute();
}
输出结果:
C:\android\java\jdk1.8\bin\java.exe
满减促销,满100减50
这样就将if…else…消除了,并且简化了代码,使得代码的业务逻辑变得优雅。
相关源码
1. Jdk中的Comparator比较器。
2. Spring中的org.springframework.core.io.Resource。
3. Spring中bean初始化使用的InstantiationStrategy。
来源:CSDN
作者:清风一阵吹我心
链接:https://blog.csdn.net/qq_32101993/article/details/104729009