首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装饰者模式的问题(我的潜在误用)

装饰者模式的问题(我的潜在误用)
EN

Stack Overflow用户
提问于 2013-08-20 16:30:11
回答 3查看 184关注 0票数 3

我试图使用装饰器模式修改我的对象的行为,但遇到了一个小问题,装饰器模式似乎无法以我想要的方式改变我的对象的功能。

下面是我要做的一个简单的例子:

我有一个类,它有一个用于int的getter和其他一些使用getter进行计算的“复杂”类。

代码语言:javascript
复制
public class MyClass implements MyInterface {
    private int value = 5;

    @Override
    public int getValue() {
        return value;
    }

    @Override
    public int complexStuff() {
        return 50 + getValue();
    }
}

我有一个抽象装饰器,它只是将接口定义的所有调用传递给MyClass实例

代码语言:javascript
复制
public abstract class MyDecorator implements MyInterface {
    private MyClass decorated;

    public MyDecorator(MyClass decorated) {
        this.decorated = decorated;
    }

    @Override
    public int getValue() {
        return decorated.getValue();
    }

    @Override
    public int complexStuff() {
        return decorated.complexStuff();
    }
}

我希望能够修饰一个MyClass实例来修改getValue()方法的行为,从而使complexStuff()也受到影响。

例如,如果我像这样装饰一个MyClass实例:

代码语言:javascript
复制
MyDecorator myDecorator = new MyDecorator(myClassInstance) {
    @Override
    public int getValue() {
        return 100;
    }
};

按照我目前的实现方式,对myDecorator.getValue()的调用将返回100,但对myDecorator.complexStuff()的调用将返回55,就好像MyClass实例尚未修饰一样。我想要的是调用myDecorator.complexStuff()返回150。

有没有办法可以修改我对装饰器模式的使用,以达到我想要的结果?或者其他一些我可以使用的模式/解决方案,让它以我想要的方式工作?

谢谢

EN

回答 3

Stack Overflow用户

发布于 2013-08-20 17:02:54

我不认为您可以使用装饰器模式来实现此目标。您正在尝试修改现有实例的行为,这不会是微不足道的(如果可能的话)。

下面这样的代码将会起作用:

代码语言:javascript
复制
public class MyClass implements MyInterface {
  private ValueProvider provider = new ValueProvider() {    
    @Override
    public int getValue() {
      return 5;
    }
  };

  // (You may wish to include this method in MyInterface)
  public void setValueProvider(ValueProvider provider) {
    this.provider = provider;
  }

  @Override
  public int getValue() {
      return provider.getValue();
  }

  @Override
  public int complexStuff() {
      return 50 + getValue();
  }
}

然后,您可以在运行时替换不同的ValueProvider。如果你愿意,一个装饰器类可以替你做这个替换。

票数 0
EN

Stack Overflow用户

发布于 2013-08-20 17:21:23

如果你不能修改MyClass,也许你可以从它派生并使用子类来代替?然后,您可以覆盖getValue

票数 0
EN

Stack Overflow用户

发布于 2018-06-09 17:17:09

你的错误是显而易见的。当您调用MyDecorator.complexStuff()是委托时,此调用直接调用到MyClass decorated委托,其中getValue()方法不会被覆盖,因为它在非MyClassMyDecorator中被覆盖。换句话说,MyDecorator 有-A MyClass,但不是-A MyClass

要解决您的问题,只需修改MyDecorator.complexStuff()方法。使用此方法,您可以自由重写getValue()方法,但不能重写complexStuff()方法:

代码语言:javascript
复制
abstract class MyDecorator implements MyInterface {

    private final MyClass decorated;

    public MyDecorator(MyClass decorated) {
        this.decorated = decorated;
    }

    // this method is overridden, and returns 100 always
    @Override
    public int getValue() {
        return decorated.getValue();
    }

    @Override
    public final int complexStuff() {
        return decorated.complexStuff() - decorated.getValue() + getValue();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18330406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档