为什么我不再推荐枚举策略模式?( 二 )

可以看到,如果策略简单的话,基于枚举的策略模式优雅许多,调用方也做到了0修改,但正确地使用枚举策略模式需要额外考虑以下几点 。

  1. 枚举的策略类是公用且静态,这意味着这个策略过程不能引入非静态的部分,扩展性受限
  2. 策略模式的目标之一,是优秀的扩展性和可维护性,最好能新增或修改某一策略类时,对其他类是无改动的 。而枚举策略如果过多或者过程复杂,维护是比较困难的,可维护性受限
四、基于工厂的策略模式为了解决良好的扩展性和可维护性,我更推荐以下利用spring自带beanFactory的优势,实现一个基于工厂的策略模式 。
策略类改动只是添加了@Service注解,并指定了Service的value属性
/** * 高价榜 * 注意申明 Service.value = https://www.isolves.com/it/cxkf/sf/2022-03-30/HighPrice,他是我们的key,下同 */@Service("HighPrice")public class HighPriceRank implements Strategy {@Overridepublic List sort(List source) {return source.stream().sorted(Comparator.comparing(Stock::getPrice).reversed()).collect(Collectors.toList());}}/** * 低价榜 */@Service("LowPrice")public class LowPriceRank implements Strategy {@Overridepublic List sort(List source) {return source.stream().sorted(Comparator.comparing(Stock::getPrice)).collect(Collectors.toList());}}/** * 高涨幅榜 */@Service("HighRise")public class HighRiseRank implements Strategy {@Overridepublic List sort(List source) {return source.stream().sorted(Comparator.comparing(Stock::getRise).reversed()).collect(Collectors.toList());}}调用类修改较大,接入借助spring工厂特性,完成策略类
@Servicepublic class RankServiceImpl {/*** dataService.getSource() 提供原始的股票数据*/@Resourceprivate DataService dataService;/*** 利用注解@Resource和@Autowired特性,直接获取所有策略类* key = @Service的value*/@Resourceprivate Map<String, Strategy> rankMap;/*** 前端传入榜单类型, 返回排序完的榜单** @param rankType 榜单类型 和Service注解的value属性一致* @return 榜单数据*/public List<Stock> getRank(String rankType) {// 判断策略是否存在if (!rankMap.containsKey(rankType)) {throw new IllegalArgumentException("rankType not found");}// 获得策略实例Strategy rank = rankMap.get(rankType);// 执行策略return rank.sort(dataService.getSource());}}若读者使用的不是Spring,也可以找找对应框架的工厂模式实现,或者自己实现一个抽象工厂
工厂策略模式会比枚举策略模式啰嗦,但也更加灵活、易扩展性和易维护 。故简单策略推荐枚举策略模式,复杂策略才推荐工厂策略模式
 
作者:ColdSmog
原文链接:
https://www.cnblogs.com/hyry/p/16068762.html




推荐阅读