3

我用最简单的术语理解装饰器模式。这个想法是一个类包装另一个类,其中装饰器方法希望在对装饰对象调用相同方法之前和/或之后运行一些其他代码。

但是,我遇到了不能简单地调用修饰方法的情况,因为它有一些不希望的副作用。但是,我确实希望运行许多装饰方法。

所以我相信我需要将装饰方法拆分为多个方法,然后在装饰器中我可以调用其中一些,运行我的装饰代码,然后调用其他一些 - 错过了我不想要的副作用。

然而,为了保持多态性,这意味着将这些方法添加到装饰对象和装饰对象实现的接口中。这是不可取的;它们不应该是公开的,这实际上意味着被装饰的类知道如何装饰它。

我相信模板模式可能更合适,其中抽象基类依次调用每个较小的方法,其中“装饰器”只是为其关心的那些提供替代实现。然而,这并不完全是“组合而不是继承”,那么你有什么建议呢?

4

2 回答 2

2

听起来模板最适合您的场景。我不会在不需要的时候强制组合......这个对话说得最好,“......这个规则的例外:当你应该使用继承时,即如果你需要对可替换性建模。”

于 2010-01-18T17:16:01.223 回答
1

听起来您的 API 违反了命令-查询分离,因此您最好的选择是重新设计 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。

于 2010-01-18T18:41:48.677 回答