细粒度装饰器模式

发布于 2024-08-18 10:09:36 字数 419 浏览 6 评论 0原文

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

但是,我遇到了无法简单地调用装饰方法的情况,因为它有一些不需要的副作用。不过,我确实希望运行大部分装饰方法。

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

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

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

I understand the Decorator pattern, in it's simplest terms. The idea being that one class wraps another, where a decorator method wishes to run some other code before and/or after calling the same method on the decorated object.

However, I have run into the situation where I cannot simply call the decorated method, as it has some undesired side-effects. However I do want much of that decorated method to run.

So I believe that I need to split the decorated method into multiple methods, then in the decorator I can call some of them, run my decorating code, then call some others - missing out the side-effect I don't want.

However in order to maintain polymorphism, that would mean adding those methods to the interface that the decorated and decorator objects implement. This is undesirable; they should not be public, and it effectively means the decorated class has knowledge of how it will be decorated.

I believe that the Template pattern is possibly more appropriate, where an abstract base class calls each of the smaller methods in turn, where the "decorator" simply supplies an alternative implementation for the ones it cares about. However this isn't exactly "composition over inheritance", so what do you recommend?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只为一人 2024-08-25 10:09:36

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

Sounds like Template suits your scenario best. I wouldn't force composition when not needed ... this conversation said it best, "...exceptions to this rule: when you should use inheritance i.e. if you need to model substitutability."

自由范儿 2024-08-25 10:09:36

听起来您的 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。

It sounds like your API violates Command-Query Separation so your best option would be to redesign the API.

However, in case I'm mistaken or redesign is not possible, perhaps you could split the method of the decorated class into two methods without changing the interface.

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);
    }
}

Notice that MyDecorator decorates MyClass instead of IMyInterface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文