首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

設計模式實作系列(十四):Command 命令模式 - 將請求封裝為物件支援佇列、日誌與復原

     編輯:關於C++

模式意圖

將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支援可復原的操作。

UML 結構圖

Command Pattern UML

核心解析

  • Command(命令): 抽象基類宣告 Execute(),具體命令綁定 Receiver 並實作執行邏輯。
  • Receiver(接收者): 真正執行業務操作的類別。
  • Invoker(調用者): 持有命令物件,觸發 Execute(),不關心具體命令細節。
  • 解耦效果: 調用者與接收者完全分離,命令物件可存儲、序列化、排隊、復原。
  • 與回呼函數關係: Command 模式是面向物件版的回呼,擁有狀態、型別安全、可組合。

C++ 完整實作

1. Command.h

#ifndef COMMAND_H
#define COMMAND_H

class Command {
public:
    virtual ~Command() {}
    virtual void Execute() = 0;
};

class Receiver {
public:
    void Action();
};

class Invoker {
public:
    Invoker(Command* pCommand);
    ~Invoker();
    void Invoke();
private:
    Command* m_pCommand;
};

class ConcreteCommand : public Command {
public:
    ConcreteCommand(Receiver* pReceiver);
    virtual ~ConcreteCommand();
    virtual void Execute();
private:
    Receiver* m_pReceiver;
};

#endif

2. Command.cpp

#include "Command.h"
#include <iostream>

void Receiver::Action() { std::cout << "Receiver Action\n"; }

Invoker::Invoker(Command* pCommand) : m_pCommand(pCommand) {}
Invoker::~Invoker() { delete m_pCommand; m_pCommand = nullptr; }
void Invoker::Invoke() { if (m_pCommand) m_pCommand->Execute(); }

ConcreteCommand::ConcreteCommand(Receiver* pReceiver) : m_pReceiver(pReceiver) {}
ConcreteCommand::~ConcreteCommand() { delete m_pReceiver; m_pReceiver = nullptr; }
void ConcreteCommand::Execute() {
    if (m_pReceiver) m_pReceiver->Action();
    std::cout << "Execute by ConcreteCommand\n";
}

3. Main.cpp

#include "Command.h"
#include <cstdlib>

int main() {
    Receiver* pReceiver = new Receiver();
    Command* pCommand = new ConcreteCommand(pReceiver);
    Invoker* pInvoker = new Invoker(pCommand);
    pInvoker->Invoke();
    delete pInvoker;
    return 0;
}

進階擴充:支援復原與巨集命令

  • Undo/Redo: 在 Command 加入虛擬 Undo(),Invoker 維護命令堆疊(std::stack<Command*>)。
  • Macro Command: 組合多個命令,Execute() 依序呼叫子命令,Undo() 逆序復原。
  • 命令佇列: 異步任務處理、執行緒池任務提交。

適用場景

  • GUI 選單/工具列按鈕(每個動作一個命令物件)。
  • 編輯器復原/重做、巨集錄製。
  • 交易系統指令佇列、工作流引擎步驟封裝。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved