【发布时间】:2009-12-11 22:21:06
【问题描述】:
我在设计、重构或“分类”中遇到了这个普遍问题:
我有一个现有的多线程 C++ 应用程序,它使用许多插件库来搜索数据。使用当前的搜索接口,给定的插件接收一个搜索字符串和一个指向 QList 对象的指针。在不同的线程上运行,该插件会搜索各种数据源(本地和网络)并将感兴趣的对象添加到列表中。当插件返回时,仍然在单独线程上的主程序将此数据添加到本地数据存储(进行进一步处理),并使用互斥锁保护此插入点。因此每个插件都可以异步返回数据。
基于 QT 的插件库基于消息传递。有相当多的插件已经为应用程序编写和测试过,它们工作得很好。
我想编写更多插件并利用现有应用程序。
问题是新插件需要应用程序提供更多信息。他们在搜索时需要间歇性地访问本地数据存储本身。所以为了得到这个,他们需要直接或间接访问存储数据的哈希数组和保护对存储的多次访问的互斥锁。我假设通过在“目录”对象中添加一个额外的方法来封装访问。
我可以看到三种编写这些新插件的方法。
加载插件时,传递它们 指向我的“目录”的指针 开始。这成为一个额外的, 新的“隐形”界面 插件。这似乎又快又容易, 根据OO完全错误但是 我看不到未来的问题会是什么。
将方法/消息添加到 现有的界面,所以我有一个 第二个功能可能是 需要新的插件库, 该消息将传递一个指向 插件的目录。这 对于插件来说很容易,但它 会使我的主要代码复杂化 似乎总体上很糟糕。
重新设计插件界面。 根据 OO,这似乎是“最好的”, 可能有其他额外的好处,但 将需要各种 重写。
所以,我的问题是
A.谁能告诉我选项 1 的具体危险?
B.是否有适合此类问题的已知模式?
编辑1:
调用插件例程的典型函数如下所示:
elsewhere(spec){
QList<CatItem> results;
plugins->getResult(spec, &results);
use_list(results);
}
...
void PluginHandler::getResults(QString* spec, QList<CatItem>* results)
{
if (id->count() == 0) return;
foreach(PluginInfo info, plugins) {
if (info.loaded)
info.obj->msg(MSG_GET_RESULTS, (void*) spec, (void*) results);
}
}
这是一个重复的代码。我宁愿延长它也不愿破坏它。
【问题讨论】:
标签: c++ multithreading design-patterns plugins refactoring