一、策略模式是什么?
策略模式是设计模式中的一种。
策略模式属于对象行为模式。
策略模式是一种行为型设计模式,用于在运行时动态地选择算法。
二、策略模式的原理
策略模式提供了一种灵活的方式来替换算法,从而使得算法的变化不会影响到使用者的代码。
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
在策略模式中,策略类用于实现具体的算法,而策略接口则定义了算法的共同接口。
三、策略模式的优点
策略模式的主要优点有:
- 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如if…else语句、switch…case语句。
- 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
- 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
- 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
- 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离
四、策略模式的应用案例
4.1 使用策略模式+工厂模式优化代码结构
实现功能:根据不同的cardId(指标ID)获取不同的指标报表的数据
具体实现的代码:
4.1.1 实现策略类
@Slf4j
@Service
public class IndexLibraryServiceImpl implements IndexLibraryService {
@Override
public AjaxResult getDataByCardId(IndexLibraryCardDto dto) {
String cardId = dto.getCardId();
return CardDataStrategyFactory.getByCardId(cardId).getData(cardId);
}
}
4.1.2 定义策略接口
定义了一个CardDataService 接口,其中包含了一个getData方法,用于执行具体的算法。由于算法的具体实现可能会因为场景的不同而不同,因此我们需要使用策略模式来动态地选择算法。
public interface CardDataService extends InitializingBean {
AjaxResult getData(String cardId);
}
4.1.3 定义工厂类
可以定义一个工厂类,用于创建具体的策略对象。
public class CardDataStrategyFactory {
private static Map<String, CardDataService> services = new ConcurrentHashMap<String, CardDataService>();
public static CardDataService getByCardId(String cardId) {
return services.get(cardId);
}
public static void register(String cardId, CardDataService cardDataService) {
services.put(cardId, cardDataService);
}
}
在上述代码中,我们定义了一个CardDataStrategyFactory 类,用于创建具体的策略对象。 在getByCardId方法中,我们根据cardId的值来创建对应的策略对象。
4.1.4 使用策略和工厂类
我们可以实现策略接口,用于具体实现算法。
此处省略多个实现策略类的代码。。。
- (1)代码1
@Component
public class CardDataBuildDurationTimeService implements CardDataService {
@Override
public void afterPropertiesSet() throws Exception {
CardDataStrategyFactory.register("build_duration_time", this);
}
@Override
public AjaxResult getData(String cardData) {
return null;
}
}
- (2)代码2
@Component
public class CardDataBuildFrequencyService implements CardDataService {
@Override
public void afterPropertiesSet() throws Exception {
CardDataStrategyFactory.register("build_frequency", this);
}
@Override
public AjaxResult getData(String cardData) {
return AjaxResult.success("CardDataBuildFrequencyService ");
}
}
- (3)代码3
@Component
public class CardDataBuildRecoveryEfficiencyervice implements CardDataService {
@Override
public void afterPropertiesSet() throws Exception {
CardDataStrategyFactory.register("build_recovery_efficiency", this);
}
@Override
public AjaxResult getData(String cardData) {
return AjaxResult.success("CardDataBuildRecoveryEfficiencyervice ");
}
}