Command(命令模式)

来源:互联网 发布:pat 端口 编辑:程序博客网 时间:2024/06/06 05:58

1、定义:

         将一个请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

2、结构图:

             

3、协作角色:

       Command 声明执行操作的接口。

       ConcreteCommand 将一个对象绑定与一个动作,调用接受者相关的操作,以实现Execute()

      Client 创建一个具体的对象并设定它的接收者

      Invoker 要求该命令执行这个请求,

     Receiver知道如何实施与一个请求相关的操作,任何类都可能成为一个接收者

4、适用性:

       对象可抽象出待执行的动作以参数化别的对象。

       在不同时刻指定、排列和执行请求。

        支持取消操作。

       支持修改日志

       用构建在原语操作上的高层操作构造一个系统

5、实现:

       1、需求:uboot上其命令按照一定的格式封装成一个对象,供客户在控制台通过输入命令调用。

       2、实现(模拟uboot命令):

 command.h

#ifndef __COMMAND_H__#define __COMMAND_H__struct cmd_tbl_s {char *name;int maxargs;int repeatable;int (*cmd)(struct cmd_tbl_s *, int , int ,char *[]);char *usage;char *help;};typedef struct cmd_tbl_s cmd_tbl_t;int cmd_init();int command_add(cmd_tbl_t *cmdtp);int cmd_del(cmd_tbl_t *cmdtp);int cmd_find_item(cmd_tbl_t **cmdtp,char *name);#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \cmd_tbl_t __u_boot_cmd_##name = {#name, maxargs, rep, cmd, usage, help}#define CONFIG_SYS_MAXARGS      16#define cmd_usage(cmdtp,st) \do {\printf("%s--%s\n",((st *)cmdtp)->name,((st *)cmdtp)->usage); \if(!((st *)cmdtp)->help)\{\printf("no help\n");\return 1;\}\printf("%s \n",((st *)cmdtp)->help);\return 0;\}while(0)#endif


cmd_nand.c

#include <stdio.h>#include <string.h>#include "command.h"int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){char *cmd;printf("%s %d\n",__func__, __LINE__);if(argc < 2)goto usage;cmd = argv[1];if(strcmp(cmd, "info") == 0){printf("\nprint nand %s\n",cmd);return 0;}else if((strncmp(cmd, "read",4) == 0)|| (strncmp(cmd, "write", 5) == 0)){printf("\nnand %s\n",cmd);return 0;}else{printf("\nnand %s\n",cmd);}usage:printf("cmdtp %p\n",cmdtp);cmd_usage(cmdtp,cmd_tbl_t);}U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,"NAND sub-system","info - show available NAND devices\n""nand read - addr off|partition size\n""nand write - addr off|partition size\n""    read/write 'size' bytes starting at offset 'off'\n""    to/from memory address 'addr', skipping bad blocks.\n");void register_nand(){command_add(&__u_boot_cmd_nand);}

 

cmd_env.c

#include <stdio.h>#include "command.h"char env[256] = "cmd env test\n";int do_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){char *cmd = NULL;if(argc < 2)goto usage;cmd = argv[1];if(strcmp(cmd, "show") == 0){printf("\nENV is :\n %s\n",env);return 0;}else if(strcmp(cmd, "store") == 0){if(argc < 3)goto usage;sprintf(env,"%s",argv[2]);return 0;}usage:cmd_usage(cmdtp,cmd_tbl_t);}U_BOOT_CMD(env,CONFIG_SYS_MAXARGS,1,do_env,"ENV sub-system","print env - env show\n""env store [string]-env store\n");void register_env(){command_add(&__u_boot_cmd_env);}

 

cmd.c

#include <stdio.h>#include <string.h>#include "command.h"#define CMD_NUM10struct cmd {cmd_tbl_t *command;int flag;};struct cmd  command[CMD_NUM];int cmd_init(){memset(command,0, sizeof(command));register_nand();register_env();}int command_add(cmd_tbl_t *cmdtp){unsigned int i;if(NULL == cmdtp)return 1;for(i = 0; i < CMD_NUM; i++){if(command[i].flag == 1)continue;elsebreak;}if(i == CMD_NUM){printf("command is full");return 1;}command[i].command = cmdtp;command[i].flag = 1;return 0;}int cmd_del(cmd_tbl_t *cmdtp){unsigned int i;if(NULL == cmdtp)return 1;for(i = 0; i < CMD_NUM; i++){if(command[i].flag == 1){if(strcmp(command[i].command->name, cmdtp->name) == 0){memset(&command[i], 0, sizeof(struct cmd));return 0;}}}return 1;}int cmd_find_item(cmd_tbl_t **cmdtp,char *name){unsigned int i;if(NULL == cmdtp)return 1;for(i = 0; i < CMD_NUM; i++){if(command[i].flag == 1){if(strcmp(command[i].command->name, name) == 0){printf("%s %d cmdtp.cmd %p\n",__func__, __LINE__,command[i].command->cmd);*cmdtp = command[i].command;return 0;}}}return 1;}


 

 

client.c

#include <stdio.h>#include <string.h>#include "command.h"int check_cmd(char *cmd){unsigned int len;unsigned int i;len = strlen(cmd);for(i = 0; i < len - 1; i++){if((cmd[i] >= 'a')&&(cmd[i] <= 'z'))continue;elsereturn 1;}return 0;}int main(int argc, char *argv[]){cmd_tbl_t *cmdtp = NULL;char *cmd;if(argc < 3){return 1;}cmd = argv[1];if(check_cmd(cmd))return 2;cmd_init();if(cmd_find_item(&cmdtp,cmd))return 3;printf("%s %d cmdtp.cmd %p\n",__func__, __LINE__,cmdtp->cmd);cmdtp->cmd(cmdtp, 0, argc - 1,&argv[1]);return 0;}

 

原创粉丝点击