Java8 将长接口方法拆分为单独的方法

Java8 splitting long interface method into separate methods

我在接口中有以下默认方法,由于有很多 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,所以接口中不能使用私有方法。我还能如何分解它并降低复杂性?任何建议将不胜感激。

为了重构您的 validate 方法以提高可读性并降低复杂性,我将应用 Extract Method重构。但是根据可用的 Java 版本,您有不同的选项 默认接口方法 .

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

Java 8

如果你被限制在 Java8 你可以 - 除了已经提到的 public 抽象方法 - 提取方法作为其他 public 默认 方法或 public static 接口方法。

这里有一个简单的重构方法,用于将方法提取到 public default 接口方法中:

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静态接口方法相同:

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 你可以 - 除了所有已经提到的选项方法 - 将方法提取为 你的接口的私有实例方法或私有静态方法。

这里有一个简单的重构方法,用于将方法提取到私有实例接口方法中:

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 static 接口方法相同:

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)会已经通知您相关信息并通过一个命令为您删除它。这已经提高了复杂性,因为该方法的整体嵌套已经减少了一层。