一、描述
有时需要向对象发送请求,但是不知道 "被请求的操作" 或 "请求的接受者" 的任何信息。在面向过程的程序设计语言中,这类通信是通过回调函数来完成的:在某个地方登记这个函数,然后在后面调用它。在面向对象程序中,command(命令)与回调函数等价,它封装了回调函数。
Command模式(命令模式)是一种对象行为模式,它可以对发送者(sender)和接收者(receiver)完全解耦(decoupling)。("发送者" 是请求操作的对象,"接收者" 是接收请求并执行某操作的对象。有了 "解耦",发送者对接收者的接口一无所知。)这里,"请求"(request)这个术语指的是要被执行的命令。Command模式还让我们可以对 "何时" 以及 "如何" 完成请求进行改变。因此,Command模式为我们提供了灵活性和可扩展性。
二、结构图
三、代码
class Transaction
{
public:
virtual ~Transaction() { }
virtual void Execute() = 0;
};
class DepositUI
{
public:
virtual ~DepositUI() { }
virtual void RequestDepositAmount() = 0;
};
class DepositTransaction : public Transaction
{
public:
DepositTransaction(DepositUI& ui) : itsDepositUI(ui) { }
~DepositTransaction() { }
public:
virtual void Execute()
{
itsDepositUI.RequestDepositAmount();
}
private:
DepositUI& itsDepositUI;
};
class WithdrawalUI
{
public:
virtual ~WithdrawalUI() { }
virtual void RequestWithDrawalAmount() = 0;
};
class WithdrawalTransaction : public Transaction
{
public:
WithdrawalTransaction(WithdrawalUI& ui) : itsWithdrawdrawalUI(ui) { }
~WithdrawalTransaction() { }
public:
virtual void Execute()
{
itsWithdrawdrawalUI.RequestWithDrawalAmount();
}
private:
WithdrawalUI& itsWithdrawdrawalUI;
};
class TransferUI
{
public:
virtual ~TransferUI() { }
virtual void RequestTransferAmount() = 0;
};
class TransferTransaction : public Transaction
{
public:
TransferTransaction(TransferUI& ui) : itsTransferUI(ui) { }
~TransferTransaction() { }
public:
virtual void Execute()
{
itsTransferUI.RequestTransferAmount();
}
private:
TransferUI& itsTransferUI;
};
class UI : public DepositUI
, public WithdrawalUI
, public TransferUI
{
public:
UI() { }
~UI() { }
public:
virtual void RequestDepositAmount()
{
printf("RequestDepositAmount Request. \n");
}
virtual void RequestWithDrawalAmount()
{
printf("RequestWithDrawalAmount Request. \n");
}
virtual void RequestTransferAmount()
{
printf("RequestTransferAmount Request. \n");
}
};
Demo代码
static UI gui;
void TransactionDemo()
{
Transaction* transaction1 = new DepositTransaction(gui);
Transaction* transaction2 = new WithdrawalTransaction(gui);
Transaction* transaction3 = new TransferTransaction(gui);
transaction1->Execute();
transaction2->Execute();
transaction3->Execute();
delete transaction1;
delete transaction2;
delete transaction3;
}