请记住,我在这里展示的示例只是为了尽可能清楚地解释问题,而不是任何真正的实现或生产代码。
另外,我们假设如果有任何东西被存储或从后端返回,它将被缓存。我从代码中省略了如何以及在何处发生这种情况的示例。
对于这个问题的范围,我们还必须假设,MyType 集合总是很小,相当静态,当应用程序启动时,它会从后端获取所有内容并重用缓存的副本,直到应用程序关闭。这就是为什么GetCached(id)
并且GetBackend(id)
实际上只是和的包装ListCached
器ListBackend
。
假设我们有以下类型的简单存储库:
public class MyRepository : IRepository<MyType>
{
public IEnumerable<MyType> GetAll()
{
// Will return cached items if present
return ListCached ?? ListBackend;
}
public MyType Get(int id)
{
return GetCached(id) ?? GetBackend(id);
}
private MyType GetBackend(int id)
{
return ListBackend.FirstOrDefault(type => type.Id == id);
}
private MyType GetCached(int id)
{
return ListCached.FirstOrDefault(type => type.Id == id);
}
protected IEnumerable<MyType> ListBackend
{
get { return Backend.GetAll<MyType>(); }
set { Backend.StoreAll<MyType>(value); }
}
public IEnumerable<MyType> ListCached
{
get { return Cache.GetAll<MyType>(); }
set { Cache.StoreAll<MyType>(value); }
}
public void Store(MyType value)
{
Backend.Store(value);
}
}
这是挑战:
class Program
{
static void Main(string[] args)
{
#region Handling Missing Objects in Cache
// We have a repository
var rep = new MyRepository();
// Into which we put stuff (3 for the demo)
rep.Store(new MyType { Id = 1 });
rep.Store(new MyType { Id = 2 });
rep.Store(new MyType { Id = 3 });
// And the repository, after this, returns 3 items
// The items are returned from cache
var count = rep.GetAll().Count(); // Returns 3
// However, somewhere else in the application, it happens so,
// for any reason, bug, programmer error, photon from sun hitting the cpu
// or tinfoil-hat left home in rush,
// that one item gets removed from the cache
Cache.Remove(new MyType { Id = 2 });
// After which, only 2 items are returned from the repository
// since the cache exists, it won't even try to hit the database
count = rep.GetAll().Count();
// Now count = 2, while WE know the backend has now 3 items
// how would the program detect it and get a fresh copy from backend?
#endregion
}
}
在这种情况下你会怎么做?是否存在有助于检测情况并从后端获取新集合的模式。最好的做法是什么?