一个组件框架的构建
组件:提供特定功能的软件实体,能够独立编译,通过不同的接口表现不同的行为。目标是实现组件开发和产品开发分离,接口和实现分离。通过注册组件可以在产品中快速的定制组件相关的功能。
1:组件定义:
明确组件的性质、用途、包含的接口
实现接口中的方法
一个组件通常由一个外部头文件和若干个实现文件组成,通过库和头文件形式发布
//组件ID,组件管理机构统一分配
#define CID_TRACE 0x00000001
//组件实例化接口,由组件提供者实现 ICOMP* insTraceComp();
2:接口定义:
明确接口的用途、范围
确定接口中的方法
接口由头文件组成,包括接口ID定义和接口定义
//接口ID,组件管理机构统一分配 #define IID_IPRINT 0x00000001 #define THIS IPRINT* //接口方法 DECLARE_INTERFACE(IPRINT) { METHOD(void,init)(THIS); METHOD(void,print)(THIS); };
3:组件管理:
分配接口ID
分配组件ID
包含注册组件的信息,根据用户申请分配组件、管理组件
4:典型流程:
系统初始化阶段:组件使用者实例化组件,将其注册到组件管理器中。
运行期间:通过组件ID查找组件获取对应的工厂指针,通过工厂创建接口实例,使用接口实例方法。
5:一个日志组件定义
- 接口实现:
DECLARE_IMPLEMENT(PRINT) { METHOD(void,init)(THIS); METHOD(void,print)(THIS); }; void init(THIS pThis); void print(THIS pThis); THIS insPrint() { PRINT *pPrint = NULL; pPrint = (PRINT*)malloc(sizeof(PRINT)); pPrint->init = init; pPrint->print = print; return (THIS)pPrint; }
- 组件工厂实现:
BOOL insInterface(ID iid,void** ppObj); ICOMPFACTORY* insTraceCompFactory() { ICOMPFACTORY* pFactory = NULL; pFactory = (ICOMPFACTORY*)malloc(sizeof(ICOMPFACTORY)); pFactory->instance = insInterface; return pFactory; } BOOL insInterface(ID iid,void** ppObj) { switch(iid) { case IID_IPRINT: *ppObj = insPrint(); break; default: break; } return TRUE; }
- 组件实现:
ICOMP* insTraceComp() { ICOMP* pComp = NULL; pComp = (ICOMP*)malloc(sizeof(ICOMP)); pComp->cid = CID_TRACE; pComp->pFactory = insTraceCompFactory(); return pComp; }
6:组件的使用:包括选择、实例化、使用组件
- 系统初始化阶段实例化、注册组件
ICOMP* pComp = NULL; //实例化组件 pComp = insTraceComp(); //注册组件 COMP_RegistComponent(pComp);
- 运行期间用户使用组件:
ICOMP* pComp = NULL; IPRINT* pPrint = NULL; //根据组件ID获取组件 COMP_GetComponent(CID_TRACE, (void**)&pComp); //根据组件工厂获取接口实例 if(NULL != pComp) { pComp->pFactory->instance(IID_IPRINT,(void**)&pPrint); } //使用接口 if(NULL != pPrint) { pPrint->init(pPrint); pPrint->print(pPrint); }
7:总结
不同的组件开发者根据接口规范可以提供不同的实现,通过组件管理机构分配唯一的组件ID,组件使用者只需要从组件管理模块获取对应组件,就可以通过组件提供的工厂方法实例化接口并使用,这里组件提供者和使用者完全分离,可以独立开发,也可以在不需要的时候快速裁剪。