建立本地缓存策略的过程实际上是一种面向接口编程思想的体现。
首先缓存策略接口应该是一个泛型接口,键的类型不知道,值的类型不知道,这是最初的想法。但是,其实所有的接口都需要一个动作就是需要锁。所以,缓存的基类接口一开始不是泛型接口,而是一个具体接口,该接口拥有锁的能力。
public interface IBaseCacheStrategy
{
ICacheLock BeginCacheLock(string resourceName, string key, int retryCount, TimeSpan retryDelay = new TimeSpan());
}
public interface ICacheLock : IDisposalbe
{
bool LockSuccessful{get;set;}
bool Lock(string resourceName);
bool Lock(string resourceName, int retryCount, TimeSpan tretryDelay);
void Unlock(string resourceName);
}
现在泛型接口该出现了,它的方法就是普通的接口所需要的方法。
//接口的继承有一个特点,就是基接口的方法不需要子类接口来实现
public interface IBaseCacheStrategy<TKey, TValue> : IBaseCacheStrategy
{
strint GetFinalKey(string key, bool isFullKey = false);
void InsertToCache(TKey key, TValue, value);
void RemoveFromCache(TKey key, bool isFullKey = false);
TValue Get(TKkey key, bool isFullKey = false);
IDictioinary<TKey, TValue> GetAll();
bool CheckExisted(TKey key, bool isFullKey=false);
long GetCount();
void Update(TKey, key, TValue, bool isFullKey=false);
}
再往下走,通常的缓存键是key, 值是object
类型,为此专门写一个存储object
的缓存策略。
public interface IObjectCacheStrategy : IBaseCacheStrategy
{
IContainerCacheStrategy ContainerCacheStrategy{get;}
}
在微信开发中,存储的不是简单的object
,为此专门写一个针对微信的缓存策略。
public interface IContainerCacheStrategy : IBaseCacheStrategy<string, IBaseContainerBag>
{
IDictionary<string TBag> GetAll<TBag> GetAll<TBag>() where TBag : IBaseContainerBag;
void UpdateContainerBag(string key, IBaseContainerBag containerBag, bool isFullKey = false);
}
很显然,IBaseContainerBag
专门用来存放有关微信的缓存。
public interface IBaseContainerBag
{
string Name{get;set;}
string Key{get;set;}
DateTime CacheTime{get;set;}
}
接口只是一种定义和约束,往下走,需要通过类的派生和继承来实现。所以,对于IBaseCacheStrategy
这个接口,需要类来一个实现该接口的类,而且很多情况下,是抽象类。
public abstract class BaseCacheStrategh : IBaseCacheStrategy
{
public abstract ICacheLock BeginCacheLock(string resourceName, string key, int retryCount=0, TimeSpan retryDelay=default);
public string GetFinalKey(string key, bool isFullKey = false)
{
//供子类调用
}
}
有了抽象基类,接下来一个实现类把缓存放在本地字典集合中。
public class LocalObjectCacheStrategy : BaseCacheStrategy, IObjectCacheStrategy
{
private IDictinary<string, object> _cache = ;
//需要为工厂创建单例
class Nested
{
static Nested(){}
internal static readonly LocalObjectCacheStrategy instance = new LocalObjectCacheStrategy();
}
public static LocalObjectCacheStrategy Instance
{
get
{
return Nested.instance;
}
}
//其它
}
然后有关容器的缓存策略既继承了LocalObjectCacheStrategy
,也实现IContainerCacheStrategy
接口。
public sealed class LocalContainerCacheStrategy : LocalObjectCacheStrategy, IContainerCacheStrategh
{
}
所有的实现类都有了,最后还需要工厂。
public class CacheStrategyFactory
{
internal static Func<IContainerCacheStrategy> ContainerCacheStrateFunc;
internal static Func<IObjectCacheStrategy> ObjectCacheStrateFunc;
pulbic static void RegisterObjectCacheStrategy(Func<IObjectCacheStrategy> func)
{
ObjectCacheStrateFunc = func;
}
public static IObjectCacheStrategy GetObjectCacheStrategyInstance()
{
if(ObjectCacheStrateFunc==null)
{
return LocalObjectCacheStrategy.Instance;
}
else
{
var instance = ObjectCacheStrateFunc();
return instance;
}
}
}