概念简介
策略模式
策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户
本文Demo需要实现的数学统计工具就是一个很好的例子,统计方式多种多样,完全可以使用策略模式这一设计模式实现
函数式接口
Java中的函数式接口,适用于函数式编程场景的接口,需要接口中仅有一个抽象方法,就可以用@FunctionalInterface
注解修饰该接口。使用时使用Lambda表达式实现
工具类实现
#1 定义统计方式
首先,定义接口之前,先定义一个枚举说明统计的方式或者说类型,这样能非常规范的定义操作和使用;这个Demo就简单的提供四种统计方式
public enum StatisticsType {
/**
* 最大值
*/
MAX,
/**
* 最小值
*/
MIN,
/**
* 平均值
*/
AVERAGE,
/**
* 求和
*/
SUM
}
#2 设计接口
这个接口被设计成为函数式接口,只提供一个方法
import java.math.BigDecimal;
import java.util.List;
/**
* 执行统计的函数式接口
*
* @author SeasonSoy
* @see xxx.MatheUtil
* @see xxx.enums.StatisticsType
*/
@FunctionalInterface
public interface MatheStatistics {
/**
* 获取数学统计值,返回一种统计结果
*
* @param c 集合,封装类型为BigDecimal
* @return BigDecimal 统计结果值
* @author SeasonSoy
*/
BigDecimal statisticsReduce(List<BigDecimal> c);
}
在这里的参数和返回值的结果被写成BigDecimal,初衷是想把工具方法做的更通用一点,类型其实可以自定义,但是我会在工具类实现中,将这个类型泛化
#3 工具类实现
毫无疑问,这里就是实现策略模式的重点,实际上也非常的简单而精简
1)策略池的实现
首先,定义一个Map,可以根据操作类型取出对应的MatheStatistics
接口实现
/**
* 统计Map
*/
private static final Map<StatisticsType, MatheStatistics> STATISTICS_MAP = new HashMap<>();
其Key的类型为刚刚定义的枚举,Value的类型用多态特性定义为接口的类型
2)对外暴露公有方法
该方法的主要思路其实就是去策略池中取出对应的策略实现,调用接口的方法就可以了
/**
* 数学统计值,返回一种统计结果
*
* @param type 统计类型
* @param c 集合,封装类型为Number类型或其子类
* @return BigDecimal 统计结果
* @throws NullPointerException if collection {@code c} is null
* @author SeasonSoy
*/
public static BigDecimal statisticsReduce(StatisticsType type, List<? extends Number> c) {
List<BigDecimal> bdList = new ArrayList<>(c.size());
for (Number number : c) {
if (number instanceof BigDecimal) {
bdList.add((BigDecimal) number);
} else {
bdList.add(BigDecimal.