我正在尝试为对象创建一个缓存机制。而我将创建一种用于创建对象的工厂方法,并在字典中跟踪现有对象。因此,如果字典中存在一个对象,我可以简单地返回它。如果对象不存在,则可以实例化一个对象,将其添加到字典中,然后返回它。
基本上,我正在创建一本单身汉词典,可以这么说。显然,我可以坚持为每种类型创建单例,然后创建一个字典。我想知道是否有更好的方法来解决这个问题,因为我目前的单子词典计划并不是那么有效。
发布于 2017-07-03 18:25:31
我给您一个想法,您可以在大量的scenarious中添加或删除该类的部分:缓存一些对象(如果需要的话,这个数量可能是有限的)
能力)
最好使用两个结构:
LinledList和字典(检索成本O(1))
将缓存的对象保存在字典中,当需要再添加一个对象时,将其添加到字典和LinkedList的末尾,当获得最大容量时,可以从LinkedList中删除第一个对象,从Dictionary中删除相同的对象,以便能够添加一个新的对象。当您想要使用某个对象时,只需返回它并在LinkedList中将其移动到末尾。
因此,您可以跟踪字典中没有重复的现有对象,并在LinkedList中得到缓存对象的“队列”,其中LinkedList的末尾是最后使用的对象。您可以根据需要实例化对象--为了简单起见,我使用了Item构造函数。
这不是一个轻量级的解决方案--对于服务器端,应该简化,避免类项(简化节点),只在LinkedList中使用键(以保持使用的有序跟踪)。
public class Item
{
public string key;
public object obj;
public Item(string k, object o) { k = key; o = obj; }
}
class MyCache
{
LinkedList<Item> ll = new LinkedList<Item>();
LinkedListNode<Item> node;
Dictionary<string, LinkedListNode<Item>> dd = new Dictionary<string, LinkedListNode<Item>>();
int capacity = 5; //just for simplicity set capacity for caching
//here you Add new object
public void Add(string key, object obj)
{
if (cap == 0) return;
//check if you already have that object
if (!dd.TryGetValue(key, out node))
{
//if capacity exceeded- remove object from beginig of LinkedList
if (dd.Count >= capacity)
RemoveItem();
Item item = new Item(key, obj);
LinkedListNode<Item> newNode = new LinkedListNode<Item>(item);
ll.AddLast(newNode);
dd.Add(key, newNode);
return;
}
//we move that object to the end of the list
ll.Remove(node);
ll.AddLast(node);
// we may update value if it was changed, like
node.Value.obj = obj;
}
// remove object from LinkedList and Dictionary
void RemoveItem()
{
LinkedListNode<Item> node = ll.First;
ll.Remove(node);
dd.Remove(node.Value.key);
}
public object Get(string key)
{
//if we have that object, we return it and move to the end of LList
if (dd.TryGetValue(key, out node))
{
ll.Remove(node);
ll.AddLast(node);
return node.Value.obj;
}
else return default(object);
}
}发布于 2017-06-28 06:26:42
这里有一个可靠的缓存解决方案,我自己使用。主要的想法很简单。利用拦截器是一种有效的解决方案。拦截器将决定从缓存中检索数据或进行服务调用。解决方案由三个不同的部分组成。第一部分是一个高度封装的存储库,它至少有四种主要的通用方法,用于注入、获取和消除(全部或特定)。如您所见,代码保证存储库中没有多余的对象。
--一个简单的仓库
public static class Repository
{
private static Dictionary<Type, object> _dictionary;
static Repository()
{
_dictionary=new Dictionary<Type, object>();
}
public static T ReadRepository<T>()
{
var type = typeof (T);
object item;
var result = _dictionary.TryGetValue(type, out item);
if (!result) return default (T);
return (T)Convert.ChangeType(item, typeof(T));
}
public static void InjectRepository<T>(object value)
{
var type = typeof(T);
object item;
var result = _dictionary.TryGetValue(type, out item);
if(result)return;
_dictionary.Add(type, value);
}
}在第二部分中,您需要创建一个名为[Cache]的自定义属性。您的逻辑方法需要由这个属性来修饰。例如,您有一个fetch方法,该方法进行服务调用以实现所需的数据。使用此属性,Interceptor将决定从缓存检索信息或让方法进行服务调用。
逻辑方法
[Cache]
public User FetchUser(string userId)
{
//...
}最突出的一点是,不允许直接调用逻辑方法。拦截器将完成这部分任务。可以利用不同的机制和模式来实现拦截器。看下面的代码。使用授权的概念,我制定了我自己的执行者。
public delegate User UserDelegation(string userID);--一种简单的阻断器
public static object Executor(UserDelegation delegation)
{
// If it is decorated witch [Cache] attribute, Fetch data from cache
// Else
delegation.Invoke(userId);
//...
}https://stackoverflow.com/questions/44794126
复制相似问题