首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为缓存对象创建单例字典的模式

为缓存对象创建单例字典的模式
EN

Stack Overflow用户
提问于 2017-06-28 05:14:14
回答 2查看 929关注 0票数 1

我正在尝试为对象创建一个缓存机制。而我将创建一种用于创建对象的工厂方法,并在字典中跟踪现有对象。因此,如果字典中存在一个对象,我可以简单地返回它。如果对象不存在,则可以实例化一个对象,将其添加到字典中,然后返回它。

基本上,我正在创建一本单身汉词典,可以这么说。显然,我可以坚持为每种类型创建单例,然后创建一个字典。我想知道是否有更好的方法来解决这个问题,因为我目前的单子词典计划并不是那么有效。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-03 18:25:31

我给您一个想法,您可以在大量的scenarious中添加或删除该类的部分:缓存一些对象(如果需要的话,这个数量可能是有限的)

能力)

最好使用两个结构:

LinledList和字典(检索成本O(1))

将缓存的对象保存在字典中,当需要再添加一个对象时,将其添加到字典和LinkedList的末尾,当获得最大容量时,可以从LinkedList中删除第一个对象,从Dictionary中删除相同的对象,以便能够添加一个新的对象。当您想要使用某个对象时,只需返回它并在LinkedList中将其移动到末尾。

因此,您可以跟踪字典中没有重复的现有对象,并在LinkedList中得到缓存对象的“队列”,其中LinkedList的末尾是最后使用的对象。您可以根据需要实例化对象--为了简单起见,我使用了Item构造函数。

这不是一个轻量级的解决方案--对于服务器端,应该简化,避免类项(简化节点),只在LinkedList中使用键(以保持使用的有序跟踪)。

代码语言:javascript
复制
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);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-06-28 06:26:42

这里有一个可靠的缓存解决方案,我自己使用。主要的想法很简单。利用拦截器是一种有效的解决方案。拦截器将决定从缓存中检索数据或进行服务调用。解决方案由三个不同的部分组成。第一部分是一个高度封装的存储库,它至少有四种主要的通用方法,用于注入、获取和消除(全部或特定)。如您所见,代码保证存储库中没有多余的对象。

--一个简单的仓库

代码语言:javascript
复制
 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将决定从缓存检索信息或让方法进行服务调用。

逻辑方法

代码语言:javascript
复制
[Cache]
public User FetchUser(string userId)
{
  //...
}

最突出的一点是,不允许直接调用逻辑方法。拦截器将完成这部分任务。可以利用不同的机制和模式来实现拦截器。看下面的代码。使用授权的概念,我制定了我自己的执行者。

代码语言:javascript
复制
public delegate User UserDelegation(string userID);

--一种简单的阻断器

代码语言:javascript
复制
 public static object Executor(UserDelegation delegation)
 {
  // If it is decorated witch [Cache] attribute, Fetch data from cache
  // Else
  delegation.Invoke(userId);
  //...
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44794126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档