【问题标题】:Java 8: Automatically composite default methods of multiple interfacesJava 8:自动组合多个接口的默认方法
【发布时间】:2017-08-22 17:41:44
【问题描述】:

我的类实现了多个具有相同默认默认方法的接口。我想知道如何从所有接口组合默认方法。例如:

interface IA {
    default void doA() {} 
    default void process() { 
        // do something 
    }
}

interface IB { 
    default void doB() {}
    default void process() { 
        // do something 
    }
}

interface IC {
    default void doC() {} 
    default void process() { 
        // do something 
    }
}

// other similar interfaces
....    

class MyClass implements IA, IB, IC, ... {
    public void process() {
       // question: how to avoid iterate all the interfaces? 
       IA.super.process();       
       IB.super.process();
       IC.super.process();
       ...
    }
}

class AnotherClass implements IA, ID, IF, IH, ... {
    public void process() {
        IA.super.process();
        ID.super.process();
        IF.super.process();
        IH.super.process();
        ...
    }
}

在实现中,该方法只是从所有接口合成process()。但是我必须明确地打电话给IA.super.process()IB.super.process()IC.super.process()。如果接口列表很长,把它们都写出来是很痛苦的。此外,我可能有不同的类来实现不同的接口组合。是否有其他语法糖/设计模式/库可以让我自动完成?

更新:与复合模式比较

复合图案也相当可观。但是我想使用默认方法作为 mixin 来给类提供不同的行为,而复合模式在这里没有给我静态类型检查。复合模式还引入了额外的内存占用。

【问题讨论】:

  • 是否需要使用默认值?你能改变你的界面吗?
  • 你确定这个类不应该委派到一个List,IA、IB等会扩展处理器吗?然后你只需使用一个循环。
  • 没有简单的方法可以让 Java 自动为您完成这项工作。您可能可以通过反射来做到这一点(检查类实现了哪些接口,然后通过反射调用每个接口的process 方法),但这将是复杂和笨重的。有不同的更好的方法,看看其他人的建议。
  • 这看起来有点滥用 default 方法的设计目的。我建议你在决定走这条路之前阅读this

标签: java design-patterns java-8 default-method


【解决方案1】:

我认为您的错误是定义了多个实际上相同的接口(除了不同的默认行为)。在我看来似乎是错误的,违反了DRY

我会使用composite pattern:

interface Processable
{
    void process();
}
public interface IA extends Processable //and IB, IC etc.
{
    default void doA()
    {
        // Do some stuff
    }
}


final class A implements IA
{
    void process() { /* whatever */ }
}


class Composite implements IA //, IB, IC etc. 
{
    List<Processable> components = Arrays.asList(
         new A(), new B(), ...
    );

    void process()
    {
         for(Processable p : components) p.process();
    }
}

【讨论】:

  • 我之前考虑过。但是当我想将复合视为 A 时,它并没有给我静态类型检查(假设 A 具有独特的行为doA())。它还增加了内存占用:维护组件列表。默认方法的工作方式类似于 mixin 函数。它赋予类不同的行为。
  • @YiqingZhu 默认方法不是 mixins。无论如何(尽可能)将它们用作 mixins 充满了各种问题。此外,此时考虑内存占用可能不是一个好主意。首先使您的代码正确且简单。如果您已经这样做了,并且内存占用成为一个实际的、可衡量的问题,那么您就可以解决它。
  • 我同意@biziclop。首先,内存占用完全可以忽略不计。而且,拥有可维护的代码绝对是一个更高的优先级。无论如何,我已经编辑了我的答案。我不确定我是否喜欢这个解决方案,因为结构变得太复杂了。不过,它应该可以工作。有一个可维护性问题,您必须确保接口Composite 实现在组件列表中表示。
  • 有些词让我立即点击那个箭头; DRY 就是其中之一。
猜你喜欢
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 2014-06-06
  • 2015-05-18
  • 1970-01-01
相关资源
最近更新 更多