【问题标题】:Validate a condition in default method in interface in Java在Java接口中验证默认方法中的条件
【发布时间】:2020-06-11 20:26:58
【问题描述】:

我的接口中有一个由许多类实现的方法:

public interface MyInterface {
    Message createMessage(List<String> rawStrings);
}

我正在向所有 createMessage 实现添加一个验证条件:

public Message createMessage(List<String> rawStrings) {
    Validate.isTrue(!rawStrings.isEmpty(), "No rawstrings present");
    .....
}

有人建议我将验证条件移至接口 - 但这样做,我将失去强制执行我的接口的类来实现此方法的机会。

这看起来是个好主意吗?

default Message createMessage(List<String> rawStrings) {
    Validate.isTrue(!rawStrings.isEmpty(), "No rawstrings present");
    return null;
}

这是对接口中默认方法的良好使用吗?我怎样才能仍然确保实现MyInterface 的类也实现方法createMessage

【问题讨论】:

  • 这对Code Review Stack Exchange 来说可能是一个更好的问题。您可能需要查找面向方面的编程和 AspectJ。

标签: java design-patterns interface default


【解决方案1】:

default 关键字的最初目的是在不破坏现有实现的情况下向现有接口添加功能。 Java 语言团队不情愿地采用了这种方法(即,不是强制 all List 实现来实现新方法,而是将 default 方法添加到 List)。一般来说,将通用代码移入default 方法是不可取的。

引入抽象基类(ABC)通常是更好的方法:

public interface MyInterface {
    Message createMessage(List<String> rawStrings);
}

public abstract class MyAbstractBaseClass implements MyInterface {

    @Override
    public Message createMessage(List<String> rawStrings) {
        Validate.isTrue(!rawStrings.isEmpty(), "No rawstrings present");
        createValidMessage(rawStrings);
    }

    protected abstract Message createValidMessage(List<String> rawStrings);
}

然后,每个实现类都扩展了 ABC:

public class MyClass extends MyAbstractBaseClass {

    @Override
    protected Message createValidMessage(List<String> rawStrings) {
        // ...do something...
    }
}

这是Template Method Pattern 的实现,它要求实现类仅提供验证后逻辑。

【讨论】:

  • 由于问题被标记为design-patterns,因此请注意这个答案是Template Method Pattern
  • @jaco0646 感谢您的建议。我已经更新了答案。
猜你喜欢
  • 2019-11-14
  • 1970-01-01
  • 2018-06-13
  • 2018-01-28
  • 2011-04-18
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多