long long ago,我写过一个DHW大话务软件,当时对命令的处理就是采用命令模式。这里简要剖析一下,所有cmd类都继承一个base抽象类,这里会用到命令模式、函数模板。
//声明一个cmd基类/接口,主要包含execute方法
class ADhwCmdExeBase
{
public:
ADhwCmdExeBase()
{
}
virtual E_DhwCmdExeStatus ExecuteCmd(T_Message *pMsg) = 0;
virtual void LogCmd(void) /* 打印正在执行的命令 */
{
}
//...
private:
WORD32 m_dwExeInst;
WORD32 m_dwExeCount; /* 当前命令执行次数,例如wait指令,定时器每超时一次,记录一次 */
E_DhwCmdExeStatus m_eCmdExeSt;
T_DhwCommand m_tExeCmd; /* cmd的id、para等 */
};
//声明具体的cmd
class CDhwCmd_ChangeGroup:public ADhwCmdExeBase
{
public:
CDhwCmd_ChangeGroup(){}
E_DhwCmdExeStatus ExecuteCmd(T_Message* pMsg); //实现具体的execute接口
};
class CDhwCmd_Delay:public ADhwCmdExeBase
{
public:
CDhwCmd_Delay(){}
E_DhwCmdExeStatus ExecuteCmd(T_Message* pMsg); //实现具体的execute接口
};
/******************cmd管理类以及cmd的动态创建机制*********************/
//函数模板:用于cmd类的实例化
template<typename T>
ADhwCmdExeBase* CreatDhwExe(void *p)
{
ADhwCmdExeBase* pClass = new(p)T;
return pClass;
}
//将上述函数模板,声明为一个类型
typedef ADhwCmdExeBase* (*CREAT_DHW_EXE)(void *p);
typedef struct
{
CREAT_DHW_EXE creat; //各cmd类的创建方法
WORD32 dwSize; //各cmd类的大小
}T_DhwCmdExeType;
class DhwCmdManager
{
public:
static DhwCmdManager* CmdManager()
{
static DhwCmdManager m_manager;
return &m_manager;
}
~DhwCmdManager()
{
}
BOOLEAN AddDhwCmd(WORD32 dwInst, T_DhwCommand tCmd);
BOOLEAN GetNextDhwCmd(WORD32 dwInst, T_DhwCommand &tCmd);
BOOLEAN IsDhwCmdFinish(WORD32 dwInst);
BOOLEAN IsDhwCmdEmpty(WORD32 dwInst);
void PrintCmdExeInfo_AllInst();
ADhwCmdExeBase* CreatExeClass(T_DhwCommand tCmd, void *p)
{
WORD32 dwCmdId = tCmd.dwCommand;
if((dwCmdId >= DHW_CMD_SET_MAX)||(p == NULL))
{
DHW_APP_ERROR_LOG(DHW_ERROR_OVERFLOW, dwCmdId, (WORD32)p);
return NULL;
}
if((m_tCmdExeClass[dwCmdId].creat != NULL)&&(m_tCmdExeClass[dwCmdId].dwSize < DHW_HANDLER_CMD_EXE_SIZE))
{
ADhwCmdExeBase *pClass = (m_tCmdExeClass[dwCmdId].creat)(p);
if(pClass != NULL)
{
pClass->SetExeCmd(tCmd);
}
else
{
ERROR_LOG(DHW_ERROR_PTR_NULL, dwCmdId, 0);
}
return pClass;
}
else
{
ERROR_LOG(DHW_ERROR_COMMON, dwCmdId, m_tCmdExeClass[dwCmdId].dwSize);
return NULL;
}
}
void ExeCmdRegister(WORD32 dwCmdId, CREAT_DHW_EXE creat, WORD32 dwSize)
{
if(dwCmdId>= DHW_CMD_SET_MAX)
{
ERROR_LOG(DHW_ERROR_OVERFLOW, dwCmdId, 0);
return;
}
m_tCmdExeClass[dwCmdId].creat = creat;
m_tCmdExeClass[dwCmdId].dwSize = dwSize;
}
BOOLEAN ReloadCmdSet();
//...
WORD32 m_dwTestCaseErrNum[DHW_TEST_CASE_NUM_MAX][DHW_EXETIMES_MAX];/*实例错误的测试用例编号*/
WORD32 m_dwTestCaseNum;
WORD32 m_dwCurTestCasePos;
char m_dwTestCaseName[DHW_TEST_CASE_NUM_MAX][DHW_TEST_CASE_NAME_LEN_MAX];
WORD16 m_wTestExeTimes[DHW_TEST_CASE_NUM_MAX];
WORD16 m_wTestCurExeTimes[DHW_TEST_CASE_NUM_MAX];
WORD32 m_dwTestCaseStepNum[DHW_INSTANCE_NUM_MAX][DHW_TEST_CASE_NUM_MAX];
T_DhwCmdCC2BPL m_apDhwCmdSet[DHW_CMD_SET_NUM_MAX];
WORD16 m_wCmdSetNum;
WORD16 m_wCurSetPos;
BOOLEAN m_bIsFinished[DHW_INSTANCE_NUM_MAX];
private:
DhwCmdManager()
{
InitDhwCmdManager();
}
private:
T_DhwCmdExeType m_tCmdExeClass[DHW_CMD_SET_MAX]; /* 记录各cmd类的创建方法和占用大小 */
WORD32 m_dwStepSum[DHW_INSTANCE_NUM_MAX]; /* 记录各实例步骤总数 */
WORD32 m_dwStepCurrent[DHW_INSTANCE_NUM_MAX]; /* 记录各实例当前正在执行的步骤索引, 例如正在执行第一条指令,该值为0 */
WORD32 m_dwExeCount[DHW_INSTANCE_NUM_MAX]; /* 用于统计各实例已执行命令数, 例如正在执行第一条指令,该值为1 */
WORD32 m_dwDIYCommand;
WORD32 m_dwCmdListExeTimes[DHW_INSTANCE_NUM_MAX];
};
//声明一个宏,用于各cmd类提交自己的创建方法和大小
#define DHW_CMD_EXE_REGISTER(CMD_ID, EXE_CLASS) \
DhwCmdManager::CmdManager()->ExeCmdRegister(CMD_ID, CreatDhwExe<EXE_CLASS>, sizeof(EXE_CLASS));
void InitExeCmdType()
{
DHW_CMD_EXE_REGISTER(DHW_CMD_CHANGE_GROUP, CDhwCmd_ChangeGroup);
DHW_CMD_EXE_REGISTER(DHW_CMD_DELAY, CDhwCmd_Delay);
}
/******************Hadler进程运行指令*********************/
WORD32 DhwAppHandlerProcess::ExecuteDhwStep(T_Message *pMsg)
{
if(pExeClass != NULL)
{
eExeResult = pExeClass->ExecuteCmd(pMsg);
}
//...
pExeClass = pCmdManager->CreatExeClass(GetCurCmd(), GetExeBuffer());
NULL_POINTER_CHECK(pExeClass);
pExeClass->LogCmd();
eExeResult = pExeClass->ExecuteCmd(pMsg);
}