利用Idea 重构功能及Java8 优化深层嵌套代码

来源:互联网 发布:中山瑞达软件 编辑:程序博客网 时间:2024/06/06 18:46

利用Idea 重构功能及Java8语法特性 优化深层嵌套代码

当遇到深层嵌套代码,如for,if,lambda表达式或内部类及这些代码的组合,这时我们可以通过Java 8的语法特性来进行优化。

下面的代码是一个嵌套循环的示例。

    public MappedField getMappedField(final String storedName) {        for (final MappedField mf : persistenceFields) {            for (final String n : mf.getLoadNames()) {                if (storedName.equals(n)) {                    return mf;                }            }        }        return null;    }

重构1:

嵌套的for/if语句通畅可以通过Java 8中的stream来替代。

Optional<String> found = persistenceFields.stream().flatMap(mappedField -> mappedField.getLoadNames().stream()).filter(storedName::equals).findFirst();

上述重构代码会返回Optional,但笔者希望返回mappedField对象,再次改造后的代码如下。

persistenceFields.stream()      .filter(mappedField -> {          for (String name : mappedField.getLoadNames()) {                                  if (storedName.equals(name)) {                                      return true;                                  }                              }                              return false;                          })         .findFirst()

重构2: 进行更好的封装

重构1还存在一些问题,我们需要了解mappedField的结构,并通过循环遍历其所有name来找到匹配的name。根据迪米特法则(Law of Demeter ),及命令-不要去询问法则(Tell, Don’t Ask), 下面代码应该由MappedField对象来提供对应的方法来判断,而不是由调用者去了解MappedField结构后去写逻辑进行判断。

        for (final MappedField mf : persistenceFields) {            if (mf.hasName(storedName)) {                return mf;            }        }

因此将上述代码提取为MappedField类中独立的方法,并命名为hasName。如果使用的IDE 是IDEA则可以通过refractor中的extract功能完成提取。
这里写图片描述

这里写图片描述

最后调用hasName方法来替代循环判断逻辑。

这里写图片描述

接着通过Idea的refractor 中的move功能将代码移动到目标类位置。
这里写图片描述

接着通过stream来重构hasName方法,hasName方法变更为下面的形式。

    public boolean hasName(String storedName) {        return getLoadNames().stream()                             .anyMatch(storedName::equals);    }

经过上述步骤最终重构后的代码为。

    public MappedField getMappedField(final String storedName) {        return persistenceFields.stream()                    .filter(mf -> mf.hasName(storedName))                    .findFirst()                    .orElse(null);    }

如需要返回Optional包装的对象则需要去掉orElse。

    public Optional<MappedField> getMappedField(final String storedName) {        return persistenceFields.stream()               .filter(mf -> mf.hasName(storedName))               .findFirst();    }

总结

这类代码特征通常为:

  1. 存在深层的循环或条件判断嵌套。
  2. 需要通过多个getter方法来访问对象内部数据。

重构方法:
考虑tell don’t ask原则,提供专用的方法供外部调用访问数据,而不是通过使用者经过多次访问去获取对象数据。并通过stream提供的操作来完成重构。

原文地址

https://blog.jetbrains.com/idea/2017/08/code-smells-deeply-nested-code/

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 剃刀龟脖子肿了怎么办 遇见有戾气的人怎么办 身上的寒气太重怎么办 身体里寒气太重怎么办 做人事招不到人怎么办 苹果6cpu坏了怎么办 苹果6s升级不了怎么办 冬天打游戏手冷怎么办 漂流瓶不能用了怎么办 感冒鼻子闻不到味道怎么办 胃难受想吐头晕怎么办 心口窝堵得慌怎么办 嘴巴里苦的很怎么办 怀孕了嘴巴好苦怎么办 嘴巴没味道想吐怎么办 手机流量不够用怎么办移动 sd卡图片不显示怎么办 苹果忘了id账号怎么办 苹果id号忘记了怎么办 7icloud存储满了怎么办 苹果6icloud满了怎么办 电脑内存槽坏了怎么办 苹果7照片删不了怎么办 屋里太冷怎么办小妙招 天气太热,没空调怎么办 8岁儿童发烧39度怎么办 4岁儿童发烧39度怎么办 6岁儿童发烧39度怎么办 手机被晒得很烫怎么办 子宫肌瘤引起的贫血怎么办 月子没做好腰疼怎么办 狗狗屁股流血水怎么办 狗狗屁股在流血怎么办 劳累引起的腰疼怎么办 心口发闷堵的慌怎么办 刨腹产后肚子大怎么办 c盘空间不够用怎么办 敷面膜玩手机了怎么办 领导想辞退我该怎么办 领导要辞退我要怎么办 想辞职老板不批怎么办