在更复杂的场景中,比如按键响应包含耗时操作、每个界面参数的读取和写入需要独立处理、并且希望更清晰地组织代码,命令模式、页面导航、和 MVVM 模式将发挥重要作用。

1. 命令模式的使用

  • 场景: 当按键触发某些耗时操作时,我们可以使用命令模式将这些操作封装起来,委托给线程池执行,从而避免主线程的阻塞。
  • 改进:命令模式: 封装每个按键操作为独立的命令对象,并将这些命令委托给线程池执行。这样可以确保耗时操作不会阻塞主线程,并且可以轻松实现操作的撤销、重做等高级功能。

命令模式(Command Pattern)

命令模式是一种行为设计模式,它将一个请求封装为一个对象,从而使得你可以用不同的请求、队列或者日志来参数化其他对象。命令模式还支持撤销操作。

命令模式的基本概念

在命令模式中,关键的参与者包括:

  • 命令(Command):命令是一个接口,声明了执行操作的接口方法(通常是 execute() 方法)。
  • 具体命令(Concrete Command):具体命令类实现了 Command 接口,包含了一个接收者对象(Receiver),并实现了该操作。具体命令将接收者对象和操作绑定在一起,调用接收者对象的操作方法来实现命令的执行。
  • 接收者(Receiver):接收者是命令要操作的对象,它包含实际执行命令的逻辑。具体命令调用接收者的方法来完成请求。
  • 调用者(Invoker):调用者是使用命令对象的类,它调用命令对象的 execute() 方法来执行命令。
  • 客户端(Client):客户端创建并配置具体命令对象,并将接收者对象与之关联。客户端还将命令对象传递给调用者。

命令模式的运作机制

  1. 客户端创建具体命令对象,并将相应的接收者对象传递给具体命令对象。
  2. 调用者持有具体命令对象的引用,并在需要时调用命令对象的 execute() 方法。
  3. 具体命令对象调用接收者对象的方法来执行请求。

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

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部