Java 如何减少复合/装饰模式中的样板代码

Java 如何减少复合/装饰模式中的样板代码,java,python,design-patterns,decorator,composite,Java,Python,Design Patterns,Decorator,Composite,在复合/装饰模式中,外部容器重写某些方法以更改行为,但必须将其余方法委托给子组件 例如:类A有10个方法,类B包含A但只重写2个方法,然后B必须重写8个方法才能委托给内部A的实例。 如何在Java和Python中剪切这些样板代码 编辑:我试着不让B扩展,因为我试着比继承更复合 我希望你只是想要这样的东西。我将以该模式为例(但您也可以将其应用于其他模式) 因此,在第/**行中,如果您想要A的行为,只需执行B扩展A,而不是扩展/实现抽象类/接口。那么你就不需要授权了。这种行为将被继承 但是,如果您想

在复合/装饰模式中,外部容器重写某些方法以更改行为,但必须将其余方法委托给子组件

例如:类A有10个方法,类B包含A但只重写2个方法,然后B必须重写8个方法才能委托给内部A的实例。 如何在Java和Python中剪切这些样板代码


编辑:我试着不让B扩展,因为我试着比继承更复合

我希望你只是想要这样的东西。我将以该模式为例(但您也可以将其应用于其他模式)

因此,在第/**行中,如果您想要A的行为,只需执行
B扩展A
,而不是扩展/实现抽象类/接口。那么你就不需要授权了。这种行为将被继承

但是,如果您想在那里执行member方法,使其更通用,并让运行时能够决定它,那么您必须进行委托。没有任何其他解决方案,因为该逻辑仅封装在成员类中,在运行时注入实际成员之前,您不知道确切的类型

您可以参考这个示例,了解如何使用实现此装饰器模式委派

public类RemovalCountingList实现列表{
@委托(excludes=ExcludedListMethods.class)
非公开最终名单代表;
private final AtomicInteger removalCount=新的AtomicInteger();
公共移除计数列表(列表委托){
this.delegate=委托;
}
@凌驾
公共E删除(int索引){
System.out.println(“删除计数:+removalCount.incrementAndGet());
返回委托。删除(索引);
}
@凌驾
公共布尔删除(对象o){
布尔值isRemoved=delegate.remove(o);
如果(已删除){
System.out.println(“删除计数:+removalCount.incrementAndGet());
}
返回被删除;
}
/**
*排除Lombok不会实现的方法,我们将实现/覆盖这些方法。
*/
私有抽象类ExcludedListMethods{
公开摘要E删除(int索引);
公共抽象布尔移除(对象o);
}
}
公共类ClientMain{
公共静态void main(字符串[]args){
RemovalCountingList cities=new RemovalCountingList(new ArrayList());
城市。添加(“伦敦”);
城市。添加(“巴黎”);
城市。添加(“伊斯坦布尔”);
城市。添加(“东京”);
字符串removedCity=cities.remove(0);
System.out.println(“移除城市:+removedCity”);
布尔值isRemoved=cities.remove(“伊斯坦布尔”);
System.out.println(“是否删除?:”+isRemoved);
}
}

它将帮助您删除样板代码。

虽然Java语言本身没有保存样板的功能,但您可以查看Lombok的
@Delegate
注释,以获得较少的样板(这就是Lombok项目所做的)。你在问题中的例子可能是这样的

interface A {

    void method1();

    void method2();

    // ... 8 more methods
}

public class B implements A {

    private interface AOverride {

        void method1();
    }

    @Delegate(types = A.class, excludes = AOverride.class)
    private final A delegate;

    public B(final A delegate) {
        this.delegate = delegate;
    }

    @Override
    public void method1() {

    }
}
这里唯一令人讨厌的是,您需要定义一个额外的类来指定要重写的方法,因为没有将方法名称作为字符串的excludes参数(这可能是一件好事,您需要编译时的安全性)。

具有实验性功能,您可以尝试:

public class DelegationExample {

  private interface SimpleCollection {
    boolean add(String item);
    boolean remove(Object item);
  }

  @Delegate(types=SimpleCollection.class)
  private final Collection<String> collection = new ArrayList<String>();
}
公共类DelegationExample{
专用接口SimpleCollection{
布尔加法(字符串项);
布尔删除(对象项);
}
@委托(类型=SimpleCollection.class)
private final Collection=new ArrayList();
}

我知道这不是Java,而是“Java”:在Kotlin中,您可以通过委托使用实现。Python可能允许您编写一个通用的
\uuuu getattr\uuuu()
方法来自动委托或代理许多方法调用:lombok就是我要找的。谢谢。
interface A {

    void method1();

    void method2();

    // ... 8 more methods
}

public class B implements A {

    private interface AOverride {

        void method1();
    }

    @Delegate(types = A.class, excludes = AOverride.class)
    private final A delegate;

    public B(final A delegate) {
        this.delegate = delegate;
    }

    @Override
    public void method1() {

    }
}
public class DelegationExample {

  private interface SimpleCollection {
    boolean add(String item);
    boolean remove(Object item);
  }

  @Delegate(types=SimpleCollection.class)
  private final Collection<String> collection = new ArrayList<String>();
}