В настоящее время мы используем шаблон проектирования декоратора для выполнения некоторого кэширования.Итак, у нас есть несколько классов, которые выглядят примерно так:
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;
}
}
Проблема заключается в том, что при вызове метода Operation () из метода AnotherOperation () реализация декоратора никогда не будет вызвана, поскольку очевидно, что декоратор не находится виерархия наследования ConcreteComponentA.
Итак, мы где-то приняли плохое дизайнерское решение или это просто ограничение шаблона проектирования декоратора, которое мы должны принять?
Обратите внимание, что в моем примере из реального мира, ConcreteComponentA - это оболочка для сторонней системы, которую мы не можем контролировать.Мы разработали IComponent и несколько POCO, с которыми работаем, чтобы абстрагировать эту стороннюю систему.В этом случае нам нужно сделать два вызова в их систему, чтобы получить необходимые данные, и это примерно то, где мы делаем эти два вызова.