代码之家  ›  专栏  ›  技术社区  ›  CodingInsomnia

数据访问模式,推拉结合?

  •  1
  • CodingInsomnia  · 技术社区  · 14 年前

    我需要一些关于将数据推/拉到应用程序中应该使用哪种模式的建议。

    我正在编写一个规则引擎,它需要在内存中保存大量数据,以便足够高效。我有一些相当矛盾的要求;

    1. 发动机在运行前必须等待所有数据的完全预加载是不可接受的。
    2. 只有按需获取和缓存数据才会导致引擎在运行足够快之前花费太长时间。
    3. 外部事件可以触发需要重新加载数据的特定部分。

    基本上,我认为我需要将数据推入和拉出到应用程序中的组合。

    我当前“模式”的简化版本如下(在psuedo-c中,用记事本编写):

    // This interface is implemented by all classes that needs the data
    interface IDataSubscriber 
    {
        void RegisterData(Entity data);
    }
    
    // This interface is implemented by the data access class
    interface IDataProvider
    {
        void EnsureLoaded(Key dataKey);
        void RegisterSubscriber(IDataSubscriber subscriber);
    }
    
    
    class MyClassThatNeedsData : IDataSubscriber
    {
        IDataProvider _provider;
    
        MyClassThatNeedsData(IDataProvider provider) 
        {
            _provider = provider;
            _provider.RegisterSubscriber(this);
        }
    
        public void RegisterData(Entity data) 
        {
            // Save data for later
            StoreDataInCache(data);
        }
    
        void UseData(Key key)
        {
            // Make sure that the data has been stored in cache
            _provider.EnsureLoaded(key);
    
            Entity data = GetDataFromCache(key);
        }
    }
    
    class MyDataProvider : IDataProvider
    {
        List<IDataSubscriber> _subscribers;
    
        // Make sure that the data for key has been loaded to all subscribers
        public void EnsureLoaded(Key key)
        {
            if (HasKeyBeenMarkedAsLoaded(key))
                return;
    
            PublishDataToSubscribers(key);
    
            MarkKeyAsLoaded(key);
        }
    
        // Force all subscribers to get a new version of the data for key
        public void ForceReload(Key key)
        {
            PublishDataToSubscribers(key);
    
            MarkKeyAsLoaded(key);
        }
    
        void PublishDataToSubscribers(Key key)
        {
            Entity data = FetchDataFromStore(key);
    
            foreach(var subscriber in _subscribers)
            {
                subscriber.RegisterData(data);
            }
        }
    }
    
    // This class will be spun off on startup and should make sure that all data is 
    // preloaded as quickly as possible
    class MyPreloadingThread 
    {
        IDataProvider _provider;
    
        MyPreloadingThread(IDataProvider provider)
        {
            _provider = provider;
        }
    
        void RunInBackground()
        {
            IEnumerable<Key> allKeys = GetAllKeys();
    
            foreach(var key in allKeys) 
            {
                _provider.EnsureLoaded(key);
            }
        }
    }
    

    不过,我觉得这不一定是最好的方法。事实上,解释它似乎需要两页纸,这似乎是一种暗示。

    有什么想法吗?有什么我应该看看的模式吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   garik    14 年前

    毫无疑问,应该是

    • 并发模式之一( active object 例如)
    • 生产者-消费者模式(队列)
    • 延迟加载(按需数据)
    • 延迟卸载模式
    • 策略模式(实现数据访问算法)
    • 多线程访问受保护 资源(缓存)

    我的投票 active object 使用共享队列(总线)+惰性模式+缓存

        2
  •  0
  •   Roman    14 年前

    你可以从一些简单的事情开始,比如一个基于 Gateway pattern . 然后你可以通过增加现金来提高绩效。