【问题标题】:can java or eclipse easily 'auto wrap' class methods that aren't being changed when using decorator patternjava或eclipse能否轻松“自动包装”使用装饰器模式时未更改的类方法
【发布时间】:2025-12-01 23:10:01
【问题描述】:

我发现有几次我正在考虑装饰器模式,并且很想不这样做只是因为包装类方法以将功能传递给我正在装饰的类可能非常乏味。写作:

 public int methodA(int argument){
     return decoratee.methodA(argument);
 }

当我只对修改其中的一两个真正感兴趣时,一遍又一遍地修改十几种方法是很乏味的。另外,如果我向类/接口添加一个新方法,如果我想向所有人公开它,我需要记住返回并将该方法添加到所有使用装饰器模式的类中。

似乎应该有一种更简单的方法来做到这一点。我的意思是理论上你可以实现一种语言能力来处理装饰器模式,就像我们处理扩展一个类一样;除了调用 super 调用装饰类之外。如果调用了装饰类的方法并且装饰器没有为其编写任何内容,则自动将调用传递给装饰类。如果装饰类想要隐藏方法,只有装饰类想要实现不同的逻辑,他才需要真正写出完整的方法。也许有一些很好的注释可以让人们快速识别装饰类的哪些方法应该可用,哪些不应该

所以 有什么可以为我做这种逻辑的吗?我的意思是我怀疑它是否像我上面描述的那样内置在 java laungae 本身中,尽管它看起来很酷,但它似乎几乎不会经常出现以证明它是合理的。不过,至少 eclipse 是否会处理此类方法的自动包装?

【问题讨论】:

  • 为什么不abstract class DecoratorAbstract extends Decoratee,然后在那里进行所有蹩脚的覆盖和构造函数。那么class Decorator extends DecoratorAbstract 会继承所有这些东西吗?
  • 尽管如此,如果到目前为止你像这样愚蠢地包装的东西的数量超过了你正在为其编写新逻辑的东西的数量,那么无论如何装饰器模式可能是一个糟糕的选择。也许您应该考虑子类化,并使用复制构造函数。

标签: java decorator


【解决方案1】:

嗯,有点。我认为您没有充分利用面向对象的世界。使用抽象类,您可以实现默认的装饰器行为,例如包装所有无聊的包装。然后你可以简单地扩展这个 Decorator 抽象类并挑选你要覆盖的东西!

类似这样的:

Decoratee.java

public interface Decoratee {
    public int methodA(int argument);
    public int methodB(int argument);
}

DecorateeA.java

public class DecorateeA implements Decoratee {
  private final Object arg1, arg2;
  public Decoratee(Object arg1, Object arg2){
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
  public int methodA(int argument){
    return someInt;
  }
  public int methodB(int argument){
    return someInt;
  }
}

装饰器.java

public abstract class Decorator implements Decoratee {
  private final Decoratee decoratee;
  public Decorator(Decoratee decoratee){
    this.decoratee = decoratee;
  }
  public int methodA(int argument){
    return decoratee.methodA(argument);
  }
  public int methodB(int argument){
    return decoratee.methodB(argument);;
  }
}

装饰器A.java

public class DecoratorA extends Decorator {
    public DecoratorA(Decoratee decoratee){
      super(decoratee);
    }
    public int methodA(int argument){
      return someOhterInt;
    }
    //methodB inherited from Decorator
}

装饰器B.java

public class DecoratorB extends Decorator {
    public DecoratorB(Decoratee decoratee){
      super(decoratee);
    }
    //methodA inherited from Decorator
    public int methodB(int argument){
      return someOhterInt;
    }
}

是的,你仍然需要包装这些东西。这里的好处是,您只需将它们包装一次 - 然后您可以构建装饰器,直到您脸色发青。

此外 - 如果您需要访问被装饰者的方法,您现在可以通过 super 关键字调用它们:

public class DecoratorC extends Decorator {
    public DecoratorC(Decoratee decoratee){
      super(decoratee);
    }
    //methodA inherited from Decorator
    public int methodB(int argument){
      return someOhterInt + super.methodB(argument);
      //super.methodB calls Decorator.methodB which calls decoratee.methodB;
    }
}

【讨论】: