Design patterns 细粒度装饰图案
我理解装饰图案,用最简单的术语来说。其思想是一个类包装另一个类,其中装饰器方法希望在对装饰对象调用相同方法之前和/或之后运行其他代码 然而,我遇到了这样的情况,我不能简单地调用修饰方法,因为它有一些不希望的副作用。但是,我确实希望运行大部分装饰过的方法 因此,我认为我需要将修饰的方法拆分为多个方法,然后在decorator中调用其中的一些方法,运行我的修饰代码,然后调用其他一些方法-忽略我不想要的副作用 然而,为了保持多态性,这意味着将这些方法添加到装饰和装饰对象实现的接口中。这是不可取的;他们不应该公开,这实际上意味着被装饰的班级知道如何装饰Design patterns 细粒度装饰图案,design-patterns,decorator,side-effects,Design Patterns,Decorator,Side Effects,我理解装饰图案,用最简单的术语来说。其思想是一个类包装另一个类,其中装饰器方法希望在对装饰对象调用相同方法之前和/或之后运行其他代码 然而,我遇到了这样的情况,我不能简单地调用修饰方法,因为它有一些不希望的副作用。但是,我确实希望运行大部分装饰过的方法 因此,我认为我需要将修饰的方法拆分为多个方法,然后在decorator中调用其中的一些方法,运行我的修饰代码,然后调用其他一些方法-忽略我不想要的副作用 然而,为了保持多态性,这意味着将这些方法添加到装饰和装饰对象实现的接口中。这是不可取的;他们
我认为模板模式可能更合适,抽象基类依次调用每个较小的方法,“装饰器”只是为它关心的方法提供一个替代实现。然而,这并不完全是“组合重于继承”,所以您有什么建议吗?听起来模板最适合您的场景。我不会在不需要的时候强制构图。。。最好的说法是,“…此规则的例外情况:何时应该使用继承,即如果需要建模可替换性。”听起来您的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。同意给定的场景听起来很像模板模式。除了名称之外,我对CQS不太熟悉-我以什么方式违反了它?我不是说你违反了CQS,但不想要的副作用通常是指向那个方向的标志。使用CQS,方法要么没有副作用,要么只有副作用。然而,在后一种情况下,副作用从来都不是多余的。