针对不同的status code,CountRecoder对象会执行不同的set方法,为不同内部属性赋值。
public CountRecoder getCountRecoder(List<CountEntry> countEntries) {
CountRecoder countRecoder = new CountRecoder();
for (CountEntry countEntry : countEntries) {
if (1 == countEntry.getCode()) {
countRecoder.setCountOfFirstStage(countEntry.getCount());
} else if (2 == countEntry.getCode()) {
countRecoder.setCountOfSecondStage(countEntry.getCount());
} else if (3 == countEntry.getCode()) {
countRecoder.setCountOfThirdtage(countEntry.getCount());
} else if (4 == countEntry.getCode()) {
countRecoder.setCountOfForthtage(countEntry.getCount());
} else if (5 == countEntry.getCode()) {
countRecoder.setCountOfFirthStage(countEntry.getCount());
} else if (6 == countEntry.getCode()) {
countRecoder.setCountOfSixthStage(countEntry.getCount());
}
}
return countRecoder;
}
CountRecoder对象用于保存一天之中六种状态分别对应的数据条目。CountEntry是对应数据库中每种状态的数据条目记录,包含状态code和以及count两个字段。上面getCountRecoder的方法实现了将list转换为CountRecoder的功能。
使用HashMap建立状态码和需要调用的方法的方法名之间的映射关系,对于每个CountEntry,首先取出状态码,然后根据状态码获得相应的要调用方法的方法名,然后使用java的反射机制就可以实现对应方法的调用了。
private static Map<Integer,String> methodsMap = new HashMap();
static
{
methodsMap.put(1, "setCountOfFirstStage");
methodsMap.put(2, "setCountOfSecondStage");
methodsMap.put(3, "setCountOfThirdtage");
methodsMap.put(4, "setCountOfForthtage");
methodsMap.put(5, "setCountOfFirthStage");
methodsMap.put(6, "setCountOfSixthStage");
}
public CountRecoder getCountRecoderByReflect(List<CountEntry> countEntries) {
CountRecoder countRecoder = new CountRecoder();
countEntries.stream().forEach(countEntry -> fillCount(countRecoder, countEntry));
return countRecoder;
}
private void fillCount(CountRecoder shippingOrderCountDto, CountEntry countEntry) {
String name = methodsMap.get(countEntry.getCode());
Method declaredMethod = null;
try {
declaredMethod = CountRecoder.class.getMethod(name, Integer.class);
declaredMethod.invoke(shippingOrderCountDto, countEntry.getCount());
} catch (NoSuchMethodException| IllegalAccessException|InvocationTargetException e) {
System.out.println(e);
}
}
本例中使用反射的确可以帮助我们完美的去掉if/else的身影,但是,反射效率很低,在高并发的条件下,反射绝对不是一个良好的选择。此外,工厂模式会引入大量的具体服务实现类,同时程序中出现大量的模板代码,使得我们程序看起来很不干净。
Java 8引入了Functional Interface,可以使用lambda表达式来去除工厂模式代码。将一个接口变为Functional interface,可以通过在接口上添加FunctionalInterface注解实现。服务实现类就可以使用一个简单的lambda表达式代替:(countRecoder, count) -> countRecoder.setCountOfFirstStage(count)
@FunctionalInterface
public interface FillCountService {
void fillCount(CountRecoder countRecoder, int count);
}
public class FillCountServieFactory {
private static Map<Integer, FillCountService> fillCountServiceMap = new HashMap<>();
static {
fillCountServiceMap.put(1, (countRecoder, count) -> countRecoder.setCountOfFirstStage(count));
fillCountServiceMap.put(2, (countRecoder, count) -> countRecoder.setCountOfSecondStage(count));
fillCountServiceMap.put(3, (countRecoder, count) -> countRecoder.setCountOfThirdtage(count));
fillCountServiceMap.put(4, (countRecoder, count) -> countRecoder.setCountOfForthtage(count));
fillCountServiceMap.put(5, (countRecoder, count) -> countRecoder.setCountOfFirthStage(count));
fillCountServiceMap.put(6, (countRecoder, count) -> countRecoder.setCountOfSixthStage(count));
}
public static FillCountService getFillCountStrategy(int statusCode) {
return fillCountServiceMap.get(statusCode);
}
}
public CountRecoder getCountRecoder(List<CountEntry> countEntries) {
CountRecoder countRecoder = new CountRecoder();
countEntries.stream().forEach(countEntry ->
FillCountServieFactory.getFillCountStrategy(countEntry.getCode())
.fillCount(countRecoder, countEntry.getCount()));
return countRecoder;
}
【参考】https://www.cnblogs.com/jun-ma/p/4967839.html