Java 8:自动合成多个接口的默认方法

Yiq*_*Zhu 3 java design-patterns java-8 default-method

我有类实现多个接口,它们具有相同的默认默认方法.我想知道如何从所有接口合成默认方法.例如:

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();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在实现中,该方法只是process()从所有接口合成.不过,我要打电话IA.super.process(),IB.super.process(),IC.super.process()作了明确规定.如果接口列表很长,那么编写所有接口列表是很痛苦的.此外,我可能有不同的类来实现不同的接口组合.是否有其他语法糖/设计模式/库允许我自动执行?

更新:与复合模式进行比较

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

Mic*_*ael 7

我认为你的错误是定义了多个有效相同的接口(除了不同的默认行为).在我看来这似乎是错误的并且违反DRY.

我会使用复合模式来构造它:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @YiqingZhu默认方法不是mixins.无论如何使用它们作为mixins(虽然可能)充满了各种各样的问题.此外,在这一点上考虑内存占用可能不是一个好主意.首先使您的代码正确和简单.如果您已经完成此操作并且内存占用成为一个实际的,可测量的问题,那么您可以解决它. (4认同)
  • 我同意@biziclop.首先,内存占用量完全可以忽略不计.但是,拥有可维护的代码肯定是一个更高的优先级.无论如何,我已经编辑了我的答案.我不确定我是否喜欢这个解决方案,因为结构太复杂了.不过应该可行.存在可维护性问题,您必须确保接口`Composite`实现在组件列表中表示. (2认同)