2014年写过一篇实现,重读一遍《设计模式》,参考网上的一篇文章,又重新写了一遍。
我体会到,c++的类在c语言里面用struct代替之后,c++的this指针可以通过传入struct本身的指针来完成。
而在command模式里的Command实际上既包含了对象(pData),又包含了命令接口(exe)。
#include <stdio.h>
#include <stdlib.h>
#include <cassert>
#define COMMAND_SLOT_MAX (2)
typedef struct _Command
{
void* pData;
void (*exe)(struct _Command* pCommand);
}Command;
typedef struct _RemoteControl
{
Command onCommands[COMMAND_SLOT_MAX];
Command offCommands[COMMAND_SLOT_MAX];
void (*setCommand)(int slot, Command onCommand, Command offCommand, struct _RemoteControl *pRemoteControl);
void (*onButtonWasPushed)(int slot, struct _RemoteControl *pRemoteControl);
void (*offButtonWasPushed)(int slot, struct _RemoteControl *pRemoteControl);
}RemoteControl;
void setCommand(int slot, Command onCommand, Command offCommand, struct _RemoteControl *pRemoteControl)
{
assert(NULL != pRemoteControl);
assert(slot < COMMAND_SLOT_MAX);
pRemoteControl->onCommands[slot] = onCommand;
pRemoteControl->offCommands[slot] = offCommand;
return;
}
void onButtonWasPushed(int slot, struct _RemoteControl *pRemoteControl)
{
assert(NULL != pRemoteControl);
assert(slot < COMMAND_SLOT_MAX);
pRemoteControl->onCommands[slot].exe(&pRemoteControl->onCommands[slot]);
return;
}
void offButtonWasPushed(int slot, struct _RemoteControl *pRemoteControl)
{
assert(NULL != pRemoteControl);
assert(slot < COMMAND_SLOT_MAX);
pRemoteControl->offCommands[slot].exe(&pRemoteControl->offCommands[slot]);
return;
}
//light device
typedef struct _Light
{
void (*on)(struct _Light* pLight);
void (*off)(struct _Light* pLight);
}Light;
void light_on_command(struct _Command* pCommand)
{
assert(NULL != pCommand);
((Light*)(pCommand->pData))->on((Light*)(pCommand->pData));
return;
}
void light_off_command(struct _Command* pCommand)
{
assert(NULL != pCommand);
((Light*)(pCommand->pData))->off((Light*)(pCommand->pData));
return;
}
void light_on(struct _Light* pLight)
{
printf("light is on!\n");
}
void light_off(struct _Light* pLight)
{
printf("light is off!\n");
}
//radio device
typedef struct _Radio
{
void (*on)(struct _Radio* pLight);
void (*off)(struct _Radio* pLight);
}Radio;
void radio_on_command(struct _Command* pCommand)
{
assert(NULL != pCommand);
((Radio*)(pCommand->pData))->on((Radio*)(pCommand->pData));
return;
}
void radio_off_command(struct _Command* pCommand)
{
assert(NULL != pCommand);
((Radio*)(pCommand->pData))->off((Radio*)(pCommand->pData));
return;
}
void radio_on(struct _Radio* pRadio)
{
printf("Radio is on!\n");
}
void radio_off(struct _Radio* pRadio)
{
printf("Radio is off!\n");
}
int main()
{
Light light;
light.on = light_on;
light.off = light_off;
Command light_on_cmd;
light_on_cmd.pData = &light;
light_on_cmd.exe = light_on_command;
Command light_off_cmd;
light_off_cmd.pData = &light;
light_off_cmd.exe = light_off_command;
Radio radio;
radio.on = radio_on;
radio.off = radio_off;
Command radio_on_cmd;
radio_on_cmd.pData = &radio;
radio_on_cmd.exe = radio_on_command;
Command radio_off_cmd;
radio_off_cmd.pData = &radio;
radio_off_cmd.exe = radio_off_command;
RemoteControl remotecontrol;
remotecontrol.setCommand = setCommand;
remotecontrol.onButtonWasPushed = onButtonWasPushed;
remotecontrol.offButtonWasPushed = offButtonWasPushed;
remotecontrol.setCommand(0, light_on_cmd, light_off_cmd, &remotecontrol);
remotecontrol.setCommand(1, radio_on_cmd, radio_off_cmd, &remotecontrol);
remotecontrol.onButtonWasPushed(0, &remotecontrol);
remotecontrol.onButtonWasPushed(1, &remotecontrol);
remotecontrol.offButtonWasPushed(0, &remotecontrol);
remotecontrol.offButtonWasPushed(1, &remotecontrol);
return 0;
}
参考文章:https://blog.csdn.net/feixiaoxing/article/details/7184325
以前写的文章:https://blog.csdn.net/hope_worker/article/details/23949593