重构多个if / else if与null检查更优雅

时间:2019-06-05 09:08:34

标签: java java-8 refactoring

如果在try / catch块内执行null检查,则我有一个倍数(如果不是)。我知道有一种更好的方法来重构它,但是考虑到我是Java 8的新手,我感到不知所措(确实有点尴尬)。

我的if else阻止

我曾尝试使用Optional.ofNullable但没有任何帮助

try {
                if (this.oldInvestigator != null) {
                    if (this.oldInvestigator.getId() == null && this.newInvestigator.getId() != null) {
                        someService.sendEmailToInvestigator(newInvestigator);

                    } else if (this.oldInvestigator.getId() != null && this.newInvestigator.getId() != null) {
                        someService.updateInvestigator(this.oldInvestigator, this.newInvestigator);

                    } else {
                        someService.sendNotificationToLeader();
                    }
                }
}

我的java类文件中有更多与此类似的条件(由我的前任提供)。我想使用Java 8或使用常见的设计实现以最佳的方式重构它们

4 个答案:

答案 0 :(得分:0)

通过反转空检查并立即返回,可以使其更具可读性。

try {
    if (this.oldInvestigator == null) {
        return;
    }
    if (this.oldInvestigator.getId() == null && this.newInvestigator.getId() != null) {
        someService.sendEmailToInvestigator(newInvestigator);

    } else if (this.oldInvestigator.getId() != null && this.newInvestigator.getId() != null) {
        someService.updateInvestigator(this.oldInvestigator, this.newInvestigator);

    } else {
        someService.sendNotificationToLeader();
    }
}

但是,这并不是真正的问题。问题是您需要重新考虑您的方法。使用空检查来确定代码中的特定路径不是理想的。问问自己为什么oldInvestigator.getId()首先应该返回null。创建oldInvestigator对象时,您应该授权提供一个ID吗?试着考虑一下如何更改基本设计,而不是尝试查看值时使外观看起来更好。

答案 1 :(得分:0)

可能会更好。 在此处的示例代码中,OldInvestigator和NewInvestigator都引用同一类;

package stackoverflow;

import java.util.Optional;


    public class OldInvestigator
    {

        //id is optional
        private Optional<String> id;

        public Optional<String> getId()
        {
            return id;
        }

        public void setId(String id)
        {
            this.id = Optional.of(id);
        }

    }

现在可以在助手类或其他服务中(确保可重用性)定义这样的逻辑(以下内容仅供参考,可根据您的业务逻辑进行重命名,移动和调整)

package stackoverflow;

import java.util.Optional;

public class Processor
{

    private static Optional<OldInvestigator> oldInvestigatorOpt = null;

    private static Optional<OldInvestigator> newInvestigatorOpt = null;

    //enum identifying who was available
    private enum InvestigatorPresence
    {
        OLD,
        NEW,
        BOTH,
        NONE
    }

    public static void main(String[] args)
    {

        switch (getInvestigatorPresence(oldInvestigatorOpt, newInvestigatorOpt)) {
            case BOTH:
                // someService.updateInvestigator(oldInvestigatorOpt.get(), newInvestigatorOpt.get())
                break;
            case NEW:
                // someService.sendEmailToInvestigator(newInvestigatorOpt.get());
                break;
            case OLD:
                // someService.sendNotificationToLeader();
                break;
            case NONE:
                // handle
                break;
            default:
                break;
        }
    }

    private static InvestigatorPresence getInvestigatorPresence(Optional<OldInvestigator> oldInvestigatorOpt,
        Optional<OldInvestigator> newInvestigatorOpt)
    {
        boolean isOldPresent = oldInvestigatorOpt.isPresent() && oldInvestigatorOpt.get().getId().isPresent();
        boolean isNewPresent = newInvestigatorOpt.isPresent() && newInvestigatorOpt.get().getId().isPresent();

        if (isOldPresent) {
            if (isNewPresent) {
                return InvestigatorPresence.BOTH;
            } else {
                return InvestigatorPresence.OLD;
            }
        } else if (isNewPresent) {
            return InvestigatorPresence.NEW;
        } else {
            return InvestigatorPresence.NONE;
        }

    }
}

答案 2 :(得分:0)

您可以拥有一个动作类,该动作类可以检查条件,然后调用您的服务或委托给下一个动作,例如

new Action<>(oldInvestigator, newInvestigator)
  .orExecute((o, n) -> o.getId() == null && n.getId() != null, (o, n) -> someService.sendEmailToInvestigator(n))
  .orExecute((o, n) -> o.getId() != null && n.getId() != null, someService::updateInvestigator)
  .orExecute((o, n) -> true,                                   (o, n) -> someService.sendNotificationToLeader());

这是Action的样子:

class Action<T1, T2> {
    private T1 o1;
    private T2 o2;
    private boolean done;

    //all args private constructor
    //two args public constructor    

    Action<T1, T2> orExecute(BiPredicate<T1, T2> biPredicate, CheckedBiConsumer<T1, T2> biConsumer) throws Exception {
        if(!done && biPredicate.test(o1, o2)) {
            biConsumer.accept(o1, o2);
            return new Action<>(o1, o2, true);
        }
        return this;
    }
}

答案 3 :(得分:-1)

仅对于null检查,您可以考虑采用以下更好的方法。

Objects.isNull(Object obj)  

Objects.nonNull(Object obj) 

当然

的版本很少
Objects.requireNonNull()