command 模式:把“做菜的厨师”和“一道菜的名字”封装起来,对外看起来就是“一道菜的名字”。然后“这道菜”就可以“被写在菜单上”,供顾客点餐。
下面是c语言的实现代码:
#include <stdio.h>
#include <stdlib.h>
//命令接口
struct command_interface
{
int (*on)(void);
int (*off)(void);
};
typedef int (*plight_method)(void);
typedef int (*pcd_method)(void);
//light
struct light
{
int light_big;
int (*light_on)(void);
int (*light_off)(void);
int (*init)(plight_method on_method, plight_method off_method, struct light *plight);
};
int my_light_on(void)
{
printf("my_light_on\n");
return 0;
}
int my_light_off(void)
{
printf("my_light_off\n");
return 0;
}
int light_init(plight_method on_method, plight_method off_method, struct light *plight)
{
plight->light_on = on_method;
plight->light_off = off_method;
return 0;
}
struct light_command
{
struct command_interface *pbase_interface;
struct light *plight_instance;
int (*init)(struct light *plight, struct light_command *plight_command);
};
int light_command_init(struct light *plight, struct light_command *plight_command)
{
plight_command->plight_instance = plight;
struct command_interface *my_command = (struct command_interface *)(&(plight_command->pbase_interface));
my_command->on = plight_command->plight_instance->light_on;
my_command->off = plight_command->plight_instance->light_off;
return 0;
}
//CD
struct cd
{
int cd_big;
int (*cd_on)(void);
int (*cd_off)(void);
int (*init)(pcd_method on_method, pcd_method off_method, struct cd *pcd);
};
int my_cd_on(void)
{
printf("my_cd_on\n");
return 0;
}
int my_cd_off(void)
{
printf("my_cd_off\n");
return 0;
}
int cd_init(pcd_method on_method, pcd_method off_method, struct cd *pcd)
{
pcd->cd_on = on_method;
pcd->cd_off = off_method;
return 0;
}
struct cd_command
{
struct command_interface *pbase_interface;
struct cd *pcd_instance;
int (*init)(struct cd *pcd, struct cd_command *pcd_command);
};
int cd_command_init(struct cd *pcd, struct cd_command *pcd_command)
{
pcd_command->pcd_instance = pcd;
struct command_interface *my_command = (struct command_interface *)(&(pcd_command->pbase_interface));
my_command->on = pcd_command->pcd_instance->cd_on;
my_command->off = pcd_command->pcd_instance->cd_off;
return 0;
}
//命令控制器
struct command_controller
{
struct command_interface * command_pointer_slot[2];
int (*set_command_slot)(struct command_interface * command_pointer, int slot, struct command_controller *pcommand_controller);
};
int set_command_slot(struct command_interface * command_pointer, int slot, struct command_controller *pcommand_controller)
{
pcommand_controller->command_pointer_slot[slot] = command_pointer;
return 0;
}
int main()
{
printf("hello world.\n");
//light命令初始化
struct light my_light = {0};
my_light.init = light_init;
my_light.init(my_light_on, my_light_off, &my_light);
struct light_command my_light_command = {0};
my_light_command.init = light_command_init;
my_light_command.init(&my_light, &my_light_command);
//cd命令初始化
struct cd my_cd = {0};
my_cd.init = cd_init;
my_cd.init(my_cd_on, my_cd_off, &my_cd);
struct cd_command my_cd_command = {0};
my_cd_command.init = cd_command_init;
my_cd_command.init(&my_cd, &my_cd_command);
//将两个命令安装到控制器中
struct command_controller my_command_controller = {0};
my_command_controller.set_command_slot = set_command_slot;
my_command_controller.set_command_slot((struct command_interface *)(&my_light_command), 0, &my_command_controller);
my_command_controller.set_command_slot((struct command_interface *)(&my_cd_command), 1, &my_command_controller);
//控制器不用关心被设置了什么命令,却可以正常的调用接口执行命令。可以动态的设置不同类型的命令到控制器中。
for (int i = 0; i < 2; i++)
{
struct command_interface *user_command = my_command_controller.command_pointer_slot[i];
user_command->on();
user_command->off();
}
getchar();
}