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

问题描述

我在接口中具有下面的方法,由于很多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 方法的复杂性,我将应用 提取方法 重构。但是根据可用的Java版本, 默认接口方法 有不同的选项。

Java 8 Java 9 中有不同的选择。在这两种情况下,您当然都可以提取方法来抽象接口方法,而这些接口方法需要实现类来实现。但是我想您也想在界面中保留提取类的默认实现代码。因此,我将不在这里解决此选项。

Java 8

如果您仅限使用 Java 8 ,则除了已经提到的公共抽象方法外,还可以将方法提取为其他 公共默认值 >方法或界面的 公共静态 方法。

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

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 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();
}

现在与将提取方法导入 私有静态 接口方法相同:

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)已经可以通知您,并可以通过单个命令将其删除。由于该方法的整体嵌套已经减少了一层,因此已经提高了复杂性。