基于枚举策略类
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 {
/**
* dataService.getSource() 提供原始的股票数据
*/
@Resource
private DataService dataService;
/**
* 前端传入榜单类型, 返回排序完的榜单
*
* @param rankType 榜单类型 形似 RankEnum.HighPrice.name()
* @return 榜单数据
*/
public List getRank(String rankType) {
// 获取策略,这里如果未匹配会抛 IllegalArgumentException异常
RankEnum rank = RankEnum.valueOf(rankType);
// 然后执行策略
return rank.sort(dataService.getSource());
}
}
基于枚举的策略模式优雅许多,调用方也做到了0修改,但正确地使用枚举策略模式需要额外考虑以下几点。
-
枚举的策略类是公用且静态,这意味着这个策略过程不能引入非静态的部分,扩展性受限
-
策略模式的目标之一,是优秀的扩展性和可维护性,最好能新增或修改某一策略类时,对其他类是无改动的。而枚举策略如果过多或者过程复杂,维护是比较困难的,可维护性受限
为了解决良好的扩展性和可维护性,我更推荐以下利用spring自带beanFactory
的优势,实现一个基于工厂的策略模式。 策略类改动只是添加了@Service
注解,并指定了Service的value属性
/**
* 高价榜
* 注意申明 Service.value = HighPrice,他是我们的key,下同
*/
@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 {
/**
* dataService.getSource() 提供原始的股票数据
*/
@Resource
private DataService dataService;
/**
* 利用注解@Resource和@Autowired特性,直接获取所有策略类
* key = @Service的value
*/
@Resource
private Map rankMap;
/**
* 前端传入榜单类型, 返回排序完的榜单
*
* @param rankType 榜单类型 和Service注解的value属性一致
* @return 榜单数据
*/
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());
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)