我很确定有更好的方法可以做到这一点,我希望得到一些反馈。
我有以下(简化):
Item
,实现IItem
Doodad
,其中包含List<IItem>
IItemExistenceVerifier
接口,需要bool ItemExists(string ItemToCheck)
StandardCachedItemExistenceVerifier
,其中包含FillCache(List<IITem> items)
DoodadValidator
接受IItemExitenceVerifier
并且Validate
方法为Doodad项目列表中的每个项目调用ItemExists(item)
。尝试在图表中表达:
StandardCachedItemExistenceVerifier
和StandardNonCachedItemVerifier
我可以传递给Doodad验证器在当前结构中:
IItemExistenceVerifier
,并且不知道它是否使用缓存。存在验证程序将提前新建,因此我无法创建新的验证程序并在构造函数中传递项目。 FillCache()
作为验证的一部分,因为界面不需要它。也许我可以:
FillCache()
上实施StandardNonCacheItemVerifier
并让它什么都不做? (这似乎是一种气味)IItemExistenceVerifier
是否实现了其他某个界面(ICacheDrivenVerifier
)或其他内容,然后调用FillCache()
(如果有)?
答案 0 :(得分:2)
正如Steven blog中{{3}}所说,缓存是一个贯穿各领域的问题,因此可以使用装饰器来解决。我不知道你的最终目标,但我认为它是if the cache exists, use cache. If not, get from query and put in cache
。
你需要的是将操作分成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
注入,其中可以是标准的或缓存的。
new StandardItemExistanceVerifier( new CachedStandardItemRetriever(new StandardItemRetriever()) );
new StandardItemExistanceVerifier( new StandardItemRetriever() );
答案 1 :(得分:0)
验证器将收到IItemExistenceVerifier,并且不知道它是否使用缓存。
这就是为什么你有一个界面 - 隐藏实现细节。没关系。
DoodadValidator不应该关心缓存,以及IItemExistenceVerifier。只有StandardCachedItemExistenceVerifier才能像任何其他验证程序一样工作,但有缓存。
怎么做?方法ItemExists应该如下工作:
public bool ItemExists( string itemToCheck )
{
// Firstly checking if the item is already in the cache
if( this.cache.ItemExists( itemToCheck ) )
{
return true;
}
// Trying to load the item into the cache. If it doesn't exist, returning false
return this.cache.tryLoadItem( itemToCheck );
}
答案 2 :(得分:0)
以下是一个答案(我想?),如果我没有看到更好的答案,我会选择这个答案:
ICacheFillable<T>
ICacheFillable<string>
FillCacheForVerifier()
方法。 FillCacheForVerifier()
方法如下所示:
private void FillItemVerifierCache()
{
// Attempt to cast the verifier
var potentiallyCacheableVerifier =
_DoodadValidator.ItemVerifier as ICacheFillable<string>;
// if the item is cacheable
if (potentiallyCacheableVerifier != null)
{
// get all of the items into a list of strings
var cacheItems = from x in _doodad.Items select x.StringProperty;
// fill the cache with the items
potentiallyCacheableVerifier.FillCache(cacheItems);
}
}
因此,最终结果是,只有传入的项目符合其选择的ICacheFillable接口时,它才会填充缓存。
如果这不是一个好主意(并且我绝不相信),那么希望它至少可以帮助说明我认为我的问题是什么。