我很确定有更好的方法可以做到这一点,并且我想获得一些反馈。
组件
我有以下内容(简化):
- 安
Item
,它实现IItem
- 一个
Doodad
,其中包含List<IItem>
- 安
IItemExistenceVerifier
需要bool ItemExists(string ItemToCheck)
的接口(interface) - 一个
StandardCachedItemExistenceVerifier
,其中包括FillCache(List<IITem> items)
- 一个
DoodadValidator
它接受IItemExitenceVerifier
并有一个Validate
调用ItemExists(item)
的方法对于 Doodad 的项目列表中的每一项。
尝试用图表来表达这一点:
目标
- 我想要一个
StandardCachedItemExistenceVerifier
和一个StandardNonCachedItemVerifier
我可以传递给 Doodad 验证器
问题/问题
在当前结构中:
- 验证者将收到
IItemExistenceVerifier
并且不知道它是否使用缓存。存在验证器将提前更新,因此我无法创建新的验证器并将项目传递到构造函数中)。 - 我不能总是打电话
FillCache()
作为验证的一部分,因为界面不需要它。
潜在选项
也许我可以:
- 选项 1:实现
FillCache()
就连StandardNonCacheItemVerifier
让它什么都不做吗? (这看起来像一种气味) - 选项 2:在验证器中,检查
IItemExistenceVerifier
是否实现一些其他接口(interface)(ICacheDrivenVerifier
)或其他东西,然后调用FillCache()
如果有的话?- 选项 3:比这两者都更聪明的东西。
最佳答案
正如 Steven 通常所述在他的blog ,缓存是一个跨领域的问题,因此可以使用装饰器来解决。我不知道你的最终目标,但我假设它是如果缓存存在,则使用缓存。如果没有,则从查询中获取并放入缓存
。
您需要的是将操作分为 2 个类,一个类用于检索对象,另一个类用于验证。
这是一个例子:
public interface IItemRetriever{
public IEnumerable<IItem> GetList();
}
public class StandardItemRetriever : IItemRetriever{
public IEnumerable<IItem> GetList(){
// returning the data
}
}
public class CachedStandardItemRetriever : IItemRetriever{
public CachedStandardItemRetriever(StandardItemRetriever standardItemRetriever){
// property assignment
}
IEnumerable<IItem> items;
public IEnumerable<IItem> GetList(){
if(items == null || !items.Any())
{
items = this.standardItemRetriever.GetList();
}
return items;
}
}
public class StandardItemExistanceVerifier{
public StandardItemExistanceVerifier(IItemRetriever iItemRetriever){
// property assignment
}
}
有了这个,您的验证器将只需要由 IItemRetriever
注入(inject),其中可以是标准的或缓存的。
new StandardItemExistanceVerifier( new CachedStandardItemRetriever(new StandardItemRetriever()) );
new StandardItemExistanceVerifier( new StandardItemRetriever() );
关于C#类设计: strategy pattern with some classes that have caching functionality?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19524920/