基于枚举策略类
public enum RankEnum {
// 以下三个为策略实例
HighPrice {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getPrice).reversed())
.collect(Collectors.toList());
}
},
LowPrice {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getPrice))
.collect(Collectors.toList());
}
},
HighRise {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getRise).reversed())
.collect(Collectors.toList());
}
};
// 这里定义了策略接口
public abstract List sort(List source);
}
对应的调用类也得以优化,榜单实例RankServiceImpl
@Service
public class RankServiceImpl {
@Resource
private DataService dataService;
public List getRank(String rankType) {
// 获取策略,这里如果未匹配会抛 IllegalArgumentException异常
RankEnum rank = RankEnum.valueOf(rankType);
// 然后执行策略
return rank.sort(dataService.getSource());
}
}
基于枚举的策略模式优雅许多,调用方也做到了0修改,但正确地使用枚举策略模式需要额外考虑以下几点。
-
枚举的策略类是公用且静态,这意味着这个策略过程不能引入非静态的部分,扩展性受限
-
策略模式的目标之一,是优秀的扩展性和可维护性,最好能新增或修改某一策略类时,对其他类是无改动的。而枚举策略如果过多或者过程复杂,维护是比较困难的,可维护性受限
为了解决良好的扩展性和可维护性,我更推荐以下利用spring自带beanFactory的优势,实现一个基于工厂的策略模式。 策略类改动只是添加了@Service注解,并指定了Service的value属性
@Service("HighPrice")
public class HighPriceRank implements Strategy {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getPrice).reversed())
.collect(Collectors.toList());
}
}
@Service("LowPrice")
public class LowPriceRank implements Strategy {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getPrice))
.collect(Collectors.toList());
}
}
@Service("HighRise")
public class HighRiseRank implements Strategy {
@Override
public List sort(List source) {
return source.stream()
.sorted(Comparator.comparing(Stock::getRise).reversed())
.collect(Collectors.toList());
}
}
调用类修改较大,接入借助spring工厂特性,完成策略类
@Service
public class RankServiceImpl {
@Resource
private DataService dataService;
@Resource
private Map rankMap;
public List getRank(String rankType) {
// 判断策略是否存在
if (!rankMap.containsKey(rankType)) {
throw new IllegalArgumentException("rankType not found");
}
// 获得策略实例
Strategy rank = rankMap.get(rankType);
// 执行策略
return rank.sort(dataService.getSource());
}
}



