java反射去除if_使用Java8函数式接口去除if/else

原代码:

针对不同的status code,CountRecoder对象会执行不同的set方法,为不同内部属性赋值。

public CountRecoder getCountRecoder(List 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的功能。

重构1 — 反射

使用HashMap建立状态码和需要调用的方法的方法名之间的映射关系,对于每个CountEntry,首先取出状态码,然后根据状态码获得相应的要调用方法的方法名,然后使用java的反射机制就可以实现对应方法的调用了。

private static Map 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 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的身影,但是,反射效率很低,在高并发的条件下,反射绝对不是一个良好的选择。此外,工厂模式会引入大量的具体服务实现类,同时程序中出现大量的模板代码,使得我们程序看起来很不干净。

重构2 — Java8对模式设计的精简:Functional Interface

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 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 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值