我理解Decorator模式,用最简单的术语来说。这个想法是一个类包装另一个类,其中装饰器方法希望在装饰对象上调用相同方法之前和/或之后运行一些其他代码。
然而,我遇到了一个我不能简单地调用装饰方法的情况,因为它有一些不受欢迎的副作用。但是我做想要运行这个装饰方法的大部分。
所以我相信我需要将装饰方法拆分为多个方法,然后在装饰器中我可以调用其中的一些,运行我的装饰代码,然后调用其他方法 - 错过了我不想要的副作用
但是,为了保持多态性,这意味着将这些方法添加到装饰和装饰器对象实现的接口。这是不可取的;它们不应该是公开的,它实际上意味着装饰的阶级知道它将如何装饰。
我认为模板模式可能更合适,抽象基类依次调用每个较小的方法,其中“装饰器”只为它关心的那些提供替代实现。然而,这并不完全是“构图而非继承”,所以你推荐什么?
答案 0 :(得分:2)
听起来像模板最适合你的场景。在不需要的时候我不会强迫组合...... this conversation说得最好,“......这个规则的例外:你应该使用继承,即如果你需要模拟可替代性。”
答案 1 :(得分:1)
听起来您的API违反了Command-Query Separation,因此您最好的选择是重新设计API。
但是,如果我错了或重新设计是不可能的,也许您可以将装饰类的方法拆分为两种方法,而无需更改界面。
public interface IMyInterface
{
Foo GetFoo(Bar bar);
}
public class MyClass : IMyInterface
{
public Foo GetFoo(Bar bar)
{
this.DoSomethingWithSideEffects(bar);
return this.DoSomethingToGetFoo(bar);
}
public Foo DoSomethingToGetFoo(Bar bar)
{
// ...
}
public void DoSomethingWithSideEffects(Bar bar)
{
// ...
}
}
public class MyDecorator : IMyInterface
{
private readonly MyClass mc;
public MyDecorator(MyClass mc)
{
// put Null Guard here...
this.mc = mc;
}
public Foo GetFoo(Bar bar)
{
return this.mc.DoSomethingToGetFoo(bar);
}
}
请注意,MyDecorator会修饰MyClass而不是IMyInterface。