工业软件架构 - 事件驱动 - 2
在更复杂的场景中,比如按键响应包含耗时操作、每个界面参数的读取和写入需要独立处理、并且希望更清晰地组织代码,命令模式、页面导航、和 MVVM 模式将发挥重要作用。
1. 命令模式的使用
- 场景: 当按键触发某些耗时操作时,我们可以使用命令模式将这些操作封装起来,委托给线程池执行,从而避免主线程的阻塞。
- 改进:命令模式: 封装每个按键操作为独立的命令对象,并将这些命令委托给线程池执行。这样可以确保耗时操作不会阻塞主线程,并且可以轻松实现操作的撤销、重做等高级功能。
命令模式(Command Pattern)
命令模式是一种行为设计模式,它将一个请求封装为一个对象,从而使得你可以用不同的请求、队列或者日志来参数化其他对象。命令模式还支持撤销操作。
命令模式的基本概念
在命令模式中,关键的参与者包括:
- 命令(Command):命令是一个接口,声明了执行操作的接口方法(通常是 execute() 方法)。
- 具体命令(Concrete Command):具体命令类实现了 Command 接口,包含了一个接收者对象(Receiver),并实现了该操作。具体命令将接收者对象和操作绑定在一起,调用接收者对象的操作方法来实现命令的执行。
- 接收者(Receiver):接收者是命令要操作的对象,它包含实际执行命令的逻辑。具体命令调用接收者的方法来完成请求。
- 调用者(Invoker):调用者是使用命令对象的类,它调用命令对象的 execute() 方法来执行命令。
- 客户端(Client):客户端创建并配置具体命令对象,并将接收者对象与之关联。客户端还将命令对象传递给调用者。
命令模式的运作机制
- 客户端创建具体命令对象,并将相应的接收者对象传递给具体命令对象。
- 调用者持有具体命令对象的引用,并在需要时调用命令对象的 execute() 方法。
- 具体命令对象调用接收者对象的方法来执行请求。
1. 定义命令接口
首先,我们定义一个 Command 接口,该接口声明了 execute() 方法。
class Command
{
public:
virtual ~Command() {
}
virtual void execute() = 0;
};
2. 实现具体命令
具体命令实现了 Command 接口,并将接收者对象与特定的操作绑定在一起。
class ExpensiveOperationCommand : public Command
{
public:
ExpensiveOperationCommand(SensorModule *sensorModule, int sensorId,
Page1ViewModel *sourceViewModel, Page2ViewModel *targetViewModel,
HardwareControlModule *hardwareModule, int operationId)
: sensorModule(sensorModule)
, sensorId(sensorId)
, sourceViewModel(sourceViewModel)
, targetViewModel(targetViewModel)
, hardwareModule(hardwareModule)
, operationId(operationId) {
}
void execute() override
{
// 获取源 ViewModel 的信息
QVariant sourceInfo = sourceViewModel->getParameter("someKey");
double sensorValue = sensorModule->getSensorData(sensorId);
// 将耗时操作移到后台线程执行
QtConcurrent::run([this]()
{
// 假设有个复杂的计算或操作基于 sourceInfo和sensorValue
hardwareModule->performOperation(operationId,sourceInfo, sensorValue);
// 更新目标 ViewModel
QMetaObject::invokeMethod(targetViewModel, [this, result]() {
targetViewModel->setParameter("resultKey", result);
}, Qt::QueuedConnection);
});
}
private:
Page1ViewModel *sourceViewModel;
Page2ViewModel *targetViewModel;
HardwareControlModule *hardwareModule;
int operationId;
};
3. 调用者类
调用者(Invoker)持有命令对象的引用,可以是一个用户界面按钮,也可以是另一个触发器。在需要执行命令时,调用者调用 execute() 方法。
在 ButtonHandlerModule 中,可以将按键操作绑定到命令对象,并在触发时执行命令。
void ButtonHandlerModule::handleButtonPress(int buttonId)
{
Comma
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 工业软件架构2:(QT和C++实现)
发表评论 取消回复