Это, вероятно, проще всего объяснить с помощью кода (это, конечно, не фактический код, но он имеет те же свойства):
У меня есть интерфейс, который выглядит примерно так:
public interface ISomeProvider
{
object GetFoo1(); //<-- This needs caching
//These others don't
object GetFoo2();
object GetFoo3();
//And let's say 20 more
}
И это имеет такую реализацию:
//NOTE: Sealed class otherwise we could inherit from it
public sealed class SuperCleverProvider : ISomeProvider
{
public object GetFoo1()
{
return "a";
}
public object GetFoo2()
{
return "b";
}
public object GetFoo3()
{
return "b";
}
}
Теперь один из этих вызовов, скажем, GetFoo1, действительно тяжелый, поэтому я хочу предоставить новую версию интерфейса, где вызовы к нему кэшируются, используя экземпляр старого.
Я сейчас так делаю:
public class CachedSuperCleverProvider : ISomeProvider
{
private readonly SuperCleverProvider _provider;
public CachedSuperCleverProvider(SuperCleverProvider provider)
{
_provider = provider;
}
private object UsingCache<T>(string cacheKey, Func<T> eval)
{
//Pretend this does caching. This is not related to the question
throw new NotImplementedException();
}
public object GetFoo1()
{
return UsingCache("foo1", _provider.GetFoo1);
}
//The code below this point is what I want to get rid of
public object GetFoo2()
{
return _provider.GetFoo2();
}
public object GetFoo3()
{
return _provider.GetFoo3();
}
//And so on for all the rest
}
У этого есть две проблемы (по крайней мере):
- Каждый раз, когда кто-то добавляет метод в интерфейс, я должен изменить его, даже если я не хочу, чтобы этот новый метод кэшировался
- Я получаю этот огромный список бесполезного кода, который просто вызывает основную реализацию.
Может кто-нибудь придумать способ сделать это, у которого нет этих проблем?