我们目前正在使用装饰设计模式来执行一些缓存。因此,我们有一堆看起来像这样的类:使用装饰设计模式时出现问题
interface IComponent
{
object Operation();
object AnotherOperation();
}
public ConcreteComponentA : IComponent
{
public object Operation()
{
return new object();
}
public object AnotherOperation()
{
return new object();
}
}
public ConcreteDecoratorA : IComponent
{
protected IComponent component;
public object Operation()
{
if(!this.cache.Contains("key")
{
this.cache["key"] = this.component.Operation();
}
return this.cache["key"];
}
因此,如果客户想使用缓存,他们将创建一个新的ConcreteDecoratorA并在ConcreteComponentA传递给构造函数。我们面临的问题是,想象AnotherOperation()需要调用Operation才能完成它的工作。 ConcreteComponentA现在看起来是这样的:
public ConcreteComponentA : IComponent
{
public object Operation()
{
return new object();
}
public object AnotherOperation()
{
object a = this.Operation();
// Do some other work
return a;
}
}
的问题是,从内AnotherOperation()方法调用运行()方法时,装饰实现将永远不会被调用,因为很明显的装饰是不是在继承层次ConcreteComponentA。
所以我们在某个地方做了一个糟糕的设计决定,或者这只是我们必须接受的装饰设计模式的一个限制吗?
请注意,在我的真实世界示例中,ConcreteComponentA是我们无法控制的第三方系统的包装。我们已经开发出了IComponent和一系列POCO,我们将它们用于抽象出第三方系统。在这种情况下,为了获得所需的数据,我们必须对其系统进行两个调用,这就是我们进行这两个调用的位置。
您是否无法控制ConcreteComponentA或由ConcreteComponentA包装的第三方系统? – dtb 2010-10-04 22:06:13
是的,ConcreteComponentA是我们的课程之一。由于政治,预算等原因,在第三方系统中改变事情是困难的,而且对于这样的事情极不可能。所以IComponent定义了我们想要使用的单个操作,但由于其服务的结构,我们需要在ConcreteComponentA中的单个操作中进行多次调用。 – 2010-10-04 22:23:36