if-statement - Java8将长接口(interface)方法拆分为单独的方法

标签 if-statement java-8 interface refactoring access-modifiers

我在接口(interface)中有以下默认方法,由于有许多 if-else 条件,它似乎非常复杂。

       default void validate() {
         Application application = application().get();
            if (StringUtils.isEmpty(application.name()) || application.data() == null) {
               throw new IllegalArgumentException());
            } else {
               for (Form form : application.data().forms) {
                   if (StringUtils.isEmpty(form.getId())) {
                        throw new IllegalArgumentException();
                   }
                     for (Question question : form.getQuestions()) {
                         if (StringUtils.isEmpty(question.getQuestion())
                            || StringUtils.isEmpty(question.getValue())) {
                               throw new IllegalArgumentException();
                         }
                      }
                }
            }
        }

我想将其分成不同的方法以降低复杂性。但是,由于项目配置为使用 Java8,因此无法在接口(interface)中使用私有(private)方法。我还能如何分解它并降低复杂性?任何建议将不胜感激。

最佳答案

为了重构以提高验证方法的可读性并降低复杂性,我将应用提取方法重构。但根据可用的 Java 版本,您可以选择不同的默认接口(interface)方法

Java 8Java 9 中有不同的选项。在这两种情况下,您当然可以将方法提取为抽象接口(interface)方法,这些方法需要由实现类来实现。但我想您也希望将提取的类的默认实现代码保留在您的界面中。所以我不会在这里讨论这个选项。

Java 8

如果您仅限于Java 8,除了已经提到的公共(public)抽象方法之外,您还可以提取方法作为其他公共(public)默认> 接口(interface)的方法或公共(public)静态方法。

这是一种简单的重构方法,用于将方法提取到公共(public)默认接口(interface)方法中:

public interface ApplicationValidatorJava8WithDefaults {
    default void validate() {
        Application application = application().get();
        validateApplication(application);
        for (Form form : application.data().forms) {
            validateForm(form);
        }
    }

    default void validateApplication(Application application) {
        if (StringUtils.isEmpty(application.name()) || application.data() == null) {
            throw new IllegalArgumentException();
        }
    }

    default void validateForm(Form form) {
        if (StringUtils.isEmpty(form.getId())) {
            throw new IllegalArgumentException();
        }
        for (Question question : form.getQuestions()) {
            validateQuestion(question);
        }
    }

    default void validateQuestion(Question question) {
        if (StringUtils.isEmpty(question.getQuestion())
                || StringUtils.isEmpty(question.getValue())) {
            throw new IllegalArgumentException();
        }
    }

    Application application();
}

现在与将方法提取到公共(public)静态接口(interface)方法中相同:

public interface ApplicationValidatorJava8WithStatics {
    default void validate() {
        Application application = application().get();
        validateApplication(application);
        for (Form form : application.data().forms) {
            validateForm(form);
        }
    }

    static void validateApplication(Application application) {
        if (StringUtils.isEmpty(application.name()) || application.data() == null) {
            throw new IllegalArgumentException();
        }
    }

    static void validateForm(Form form) {
        if (StringUtils.isEmpty(form.getId())) {
            throw new IllegalArgumentException();
        }
        for (Question question : form.getQuestions()) {
            validateQuestion(question);
        }
    }

    static void validateQuestion(Question question) {
        if (StringUtils.isEmpty(question.getQuestion())
                || StringUtils.isEmpty(question.getValue())) {
            throw new IllegalArgumentException();
        }
    }

    Application application();
}

Java 9

如果您可以使用Java 9,除了所有已经提到的选项方法之外,您还可以将方法提取为私有(private)实例方法或接口(interface)的私有(private)静态方法。

这是一种简单的重构方法,用于将方法提取到私有(private)实例接口(interface)方法中:

public interface ApplicationValidatorJava9WithPrivateInstanceMethods {
    default void validate() {
        Application application = application().get();
        validateApplication(application);
        for (Form form : application.data().forms) {
            validateForm(form);
        }
    }

    private void validateApplication(Application application) {
        if (StringUtils.isEmpty(application.name()) || application.data() == null) {
            throw new IllegalArgumentException();
        }
    }

    private void validateForm(Form form) {
        if (StringUtils.isEmpty(form.getId())) {
            throw new IllegalArgumentException();
        }
        for (Question question : form.getQuestions()) {
            validateQuestion(question);
        }
    }

    private void validateQuestion(Question question) {
        if (StringUtils.isEmpty(question.getQuestion())
                || StringUtils.isEmpty(question.getValue())) {
            throw new IllegalArgumentException();
        }
    }

    Application application();
}

现在与将方法提取到私有(private)静态接口(interface)方法中相同:

public interface ApplicationValidatorJava9WithPrivateStaticMethods {
    default void validate() {
        Application application = application().get();
        validateApplication(application);
        for (Form form : application.data().forms) {
            validateForm(form);
        }
    }

    private static void validateApplication(Application application) {
        if (StringUtils.isEmpty(application.name()) || application.data() == null) {
            throw new IllegalArgumentException();
        }
    }

    private static void validateForm(Form form) {
        if (StringUtils.isEmpty(form.getId())) {
            throw new IllegalArgumentException();
        }
        for (Question question : form.getQuestions()) {
            validateQuestion(question);
        }
    }

    private static void validateQuestion(Question question) {
        if (StringUtils.isEmpty(question.getQuestion())
                || StringUtils.isEmpty(question.getValue())) {
            throw new IllegalArgumentException();
        }
    }

    Application application();
}

注意:我还删除了第一个 else 分支,因为它在第一个 if 子句中抛出异常后已过时。好的 IDE(例如 IntelliJ)已经通知您这一点,并通过一个命令为您删除它。这已经提高了复杂性,因为方法的整体嵌套已经减少了一级。

关于if-statement - Java8将长接口(interface)方法拆分为单独的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63803735/

相关文章:

java - 在 JDK8 存储库中进行更改

C# 设计 - 如何在没有空接口(interface)的情况下将类和枚举分组到列表中?

c++ - SFML 退格键不会触发多次

python - Gurobi Python == 和变量

c++ - 为什么真陈述是假的?

Javascript if 语句或运算符不起作用

java - 为什么我得到 java.lang.NoSuchMethodError : createImageUsingNativeSize error in 1. 8.0_45

java - Apache Ant 1.9.4 与 Java 1.8 的兼容性

java - Java 中 ContainsAll 的成本是多少?

go - 如何在接口(interface)上使用 strings.Contains