我需要一些关于将数据推/拉到应用程序中应该使用哪种模式的建议。
我正在编写一个规则引擎,它需要在内存中保存大量数据,以便足够高效。我有一些相当矛盾的要求;
-
发动机在运行前必须等待所有数据的完全预加载是不可接受的。
-
只有按需获取和缓存数据才会导致引擎在运行足够快之前花费太长时间。
-
外部事件可以触发需要重新加载数据的特定部分。
基本上,我认为我需要将数据推入和拉出到应用程序中的组合。
我当前“模式”的简化版本如下(在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);
}
}
}
不过,我觉得这不一定是最好的方法。事实上,解释它似乎需要两页纸,这似乎是一种暗示。
有什么想法吗?有什么我应该看看的模式吗?