发布时间: 2012-06-20 20:37:21 作者: rapoo
C语言实现《大话设计模式》中的组合模式例程#ifndef __COMPOSITE_H__#define __COMPOSITE_H__#include "rtthread.h"#include "finsh.h"//公司抽像类typedef struct _Company Company;struct _Company{ char *Name; void (*Add)(void *pCompany, void *pAddCompany); //增加 void (*Remove)(void *pCompany, void *pRemoveCompany); //移除 void (*Display)(void *pCompany, int Depth); //显示 void (*LineOfDuty)(void *pCompany); //履行职责 void (*Delete)(void *pCompany); //析构};static void CompanyDelete(void *pCompany){ rt_free(pCompany);}Company *CompanyCreate(char *Name, rt_size_t Size){ Company *pCompany = (Company *)rt_malloc(Size); pCompany->Delete = CompanyDelete; pCompany->Name = Name; return pCompany;}//LIST数组typedef struct _List List;struct _List{ void **pListPointArray; //LIST数组指针 int Total; //元素个数 void (*Add)(List *pList, void *pListPoint); //添加 void (*Remove)(List *pList, void *pListPoint); //移除 void (*Delete)(void *pList); //析构};//List类的析构函数static void ListDelete(void *pList){ if(((List *)pList)->pListPointArray != RT_NULL) //先释放指针数组 { rt_free(((List *)pList)->pListPointArray); } rt_free(pList); //再释放整个List类}//元素增加函数static void ListAdd(List *pList, void *pListPoint){ void **tListPointArray = rt_malloc(sizeof(int *) * (pList->Total + 1)); //申请比原来大一个存储单元的内存 int pListIndex; for(pListIndex = 0; pListIndex < pList->Total; pListIndex++) //拷贝 { if(pList->pListPointArray[pListIndex] == pListPoint) //判断,如果有相同的元素存在 { rt_free(tListPointArray); //释放现申请的内存 return; //返回 } tListPointArray[pListIndex] = pList->pListPointArray[pListIndex]; //拷贝 } tListPointArray[pList->Total] = pListPoint; //将添加的元素放到最后一个存储单元中 pList->Total += 1; //总数加1 if(pList->pListPointArray != RT_NULL) rt_free(pList->pListPointArray); //释放原来的内存 pList->pListPointArray = tListPointArray; //将新的句柄替换原句柄}//元素移除函数static void ListRemove(List *pList, void *pListPoint){ int pListIndex, tListIndex; void **tListPointArray; void **FreePointArray; void **SavePointArray; if(pList->Total == 0) return; //总数为0时退出 tListPointArray = rt_malloc(sizeof(int) * (pList->Total - 1)); //申请比原来小一个存储单元的内存 FreePointArray = tListPointArray; //将刚申请的内存空间作为默认的释放空间 SavePointArray = pList->pListPointArray; //将已有的内存空间作为默认的存储空间 for(pListIndex = 0, tListIndex= 0; pListIndex < pList->Total; pListIndex++) //查找移除点 { if(pList->pListPointArray[pListIndex] == pListPoint) //当前点是移除点 { FreePointArray = pList->pListPointArray; //改变释放内存指针 SavePointArray = tListPointArray; //改变保留内存指针 continue; //结束本次循环 } if(tListIndex < (pList->Total -1)) //如果当前点不是移除点,拷贝序号小于总量减1 { tListPointArray[tListIndex] = pList->pListPointArray[pListIndex]; //拷贝 tListIndex++; //拷贝序号加1 } } pList->Total = (SavePointArray == tListPointArray) ? pList->Total - 1 : pList->Total; //根据保留的内存块改变总数的值 if(FreePointArray != RT_NULL) rt_free(FreePointArray); //释放该释放的不用的内存块 pList->pListPointArray = SavePointArray; //保留该保留的}//List构造函数List *ListCreate(void){ List *pList = (List *)rt_malloc(sizeof(List)); pList->Total = 0; pList->pListPointArray = RT_NULL; pList->Add = ListAdd; pList->Remove = ListRemove; pList->Delete = ListDelete; return pList;}//具体公司类,实现接口,树叶节点typedef struct _ConcreteCompany ConcreteCompany;struct _ConcreteCompany{ Company mCompany; //继承Company类 List *Chiledren; //List };//重写父类的Add函数static void ConcreteCompanyAdd(void *pConcreteCompany, void *pAddCompany){ List *Chiledren = ((ConcreteCompany *)pConcreteCompany)->Chiledren; Chiledren->Add(Chiledren, pAddCompany);}//重写父类的Remove函数static void ConcreteCompanyRemove(void *pConcreteCompany, void *pRemoveCompany){ List *Chiledren = ((ConcreteCompany *)pConcreteCompany)->Chiledren; Chiledren->Remove(Chiledren, pRemoveCompany);}//重写父类的Display函数static void ConcreteCompanyDisplay(void *pConcreteCompany, int Depth){ int i; List *Chiledren = ((ConcreteCompany *)pConcreteCompany)->Chiledren; rt_kprintf(" "); for(i = 0; i < Depth; i++) { rt_kprintf("-"); } rt_kprintf("%s\n", ((Company *)pConcreteCompany)->Name); for(i = 0; i < Chiledren->Total; i++) { ((Company *)(Chiledren->pListPointArray[i]))->Display(Chiledren->pListPointArray[i], Depth + 2); }}//重写父类的LineOfDuty函数static void ConcreteCompanyLineOfDuty(void *pConcreteCompany){ int i; List *Chiledren = ((ConcreteCompany *)pConcreteCompany)->Chiledren; for(i = 0; i < Chiledren->Total; i++) { ((Company *)(Chiledren->pListPointArray[i]))->LineOfDuty(Chiledren->pListPointArray[i]); }}//重写析构函数static void ConcreteCompanyDelete(void *pConcreteCompany){ List *Chiledren = ((ConcreteCompany *)pConcreteCompany)->Chiledren; Chiledren->Delete(Chiledren); rt_free(pConcreteCompany);}//构造函数ConcreteCompany *ConcreteCompanyCreate(char *Name, rt_size_t Size){ ConcreteCompany *pConcreteCompany = (ConcreteCompany *)CompanyCreate(Name, Size); pConcreteCompany->Chiledren = ListCreate(); ((Company *)pConcreteCompany)->Add = ConcreteCompanyAdd; ((Company *)pConcreteCompany)->Remove = ConcreteCompanyRemove; ((Company *)pConcreteCompany)->Display = ConcreteCompanyDisplay; ((Company *)pConcreteCompany)->LineOfDuty = ConcreteCompanyLineOfDuty; ((Company *)pConcreteCompany)->Delete = ConcreteCompanyDelete; return pConcreteCompany;}//树叶节点//人力资源部typedef struct _HRDepartment HRDepartment;struct _HRDepartment{ Company mCompany; //继承};//重写父类的函数static void HRDepartmentAdd(void *pHRDepartment, void *pAddCompany){ }static void HRDepartmentRemove(void *pHRDepartment, void *pRemoveCompany){ }static void HRDepartmentDisplay(void *pHRDepartment, int Depth){ int i; rt_kprintf(" "); for(i = 0; i < Depth; i++) { rt_kprintf("-"); } rt_kprintf("%s\n", ((Company *)pHRDepartment)->Name);}static void HRDepartmentLineOfDuty(void *pHRDepartment){ rt_kprintf(" %s 员工招聘培训管理\n", ((Company *)pHRDepartment)->Name);}HRDepartment *HRDepartmentCreate(char *Name, rt_size_t Size){ HRDepartment *pHRDepartment = (HRDepartment *)CompanyCreate(Name, Size); ((Company *)pHRDepartment)->Add = HRDepartmentAdd; ((Company *)pHRDepartment)->Remove = HRDepartmentRemove; ((Company *)pHRDepartment)->Display = HRDepartmentDisplay; ((Company *)pHRDepartment)->LineOfDuty = HRDepartmentLineOfDuty; return pHRDepartment;}//财务部typedef struct _FinanceDepartment FinanceDepartment;struct _FinanceDepartment{ Company Company;};static void FinanceDepartmentAdd(void *pFinanceDepartment, void *pAddCompany){ }static void FinanceDepartmentRemove(void *pFinanceDepartment, void *pRemoveCompany){ }static void FinanceDepartmentDisplay(void *pFinanceDepartment, int Depth){ int i; rt_kprintf(" "); for(i = 0; i < Depth; i++) { rt_kprintf("-"); } rt_kprintf("%s\n", ((Company *)pFinanceDepartment)->Name);}static void FinanceDepartmentLineOfDuty(void *pFinanceDepartment){ rt_kprintf(" %s 公司财务收支管理\n", ((Company *)pFinanceDepartment)->Name);}FinanceDepartment *FinanceDepartmentCreate(char *Name, rt_size_t Size){ FinanceDepartment *pFinanceDepartment = (FinanceDepartment *)CompanyCreate(Name, Size); ((Company *)pFinanceDepartment)->Add = FinanceDepartmentAdd; ((Company *)pFinanceDepartment)->Remove = FinanceDepartmentRemove; ((Company *)pFinanceDepartment)->Display = FinanceDepartmentDisplay; ((Company *)pFinanceDepartment)->LineOfDuty = FinanceDepartmentLineOfDuty; return pFinanceDepartment;}#endif#include "Composite.h"//客户端void Composite(void){ ConcreteCompany *Root = ConcreteCompanyCreate("北京总公司", sizeof(ConcreteCompany)); ConcreteCompany *Comp = ConcreteCompanyCreate("上海华东分公司", sizeof(ConcreteCompany)); ConcreteCompany *Comp1 = ConcreteCompanyCreate("南京办事处", sizeof(ConcreteCompany)); ConcreteCompany *Comp2 = ConcreteCompanyCreate("杭州办事处", sizeof(ConcreteCompany)); HRDepartment *RootHR = HRDepartmentCreate("总公司人力资源部", sizeof(HRDepartment)); FinanceDepartment *RootFD = FinanceDepartmentCreate("总公司账务部", sizeof(FinanceDepartment)); HRDepartment *CompHR = HRDepartmentCreate("华东分公司人力资源部", sizeof(HRDepartment)); FinanceDepartment *CompFD = FinanceDepartmentCreate("华东分公司账务部", sizeof(FinanceDepartment)); HRDepartment *Comp1HR = HRDepartmentCreate("南京办事处人力资源部", sizeof(HRDepartment)); FinanceDepartment *Comp1FD = FinanceDepartmentCreate("南京办事处账务部", sizeof(FinanceDepartment)); HRDepartment *Comp2HR = HRDepartmentCreate("杭州办事处人力资源部", sizeof(HRDepartment)); FinanceDepartment *Comp2FD = FinanceDepartmentCreate("杭州办事处账务部", sizeof(FinanceDepartment)); ((Company *)Root)->Add(Root, RootHR); ((Company *)Root)->Add(Root, RootFD); ((Company *)Root)->Add(Root, Comp); ((Company *)Comp)->Add(Comp, CompHR); ((Company *)Comp)->Add(Comp, CompFD); ((Company *)Comp)->Add(Comp, Comp1); ((Company *)Comp)->Add(Comp, Comp2); ((Company *)Comp1)->Add(Comp1, Comp1HR); ((Company *)Comp1)->Add(Comp1, Comp1FD); ((Company *)Comp2)->Add(Comp2, Comp2HR); ((Company *)Comp2)->Add(Comp2, Comp2FD); rt_kprintf("#############################################################################"); rt_kprintf(" 公司结构图:\n"); ((Company *)Root)->Display(Root, 1); rt_kprintf(" 职责:\n"); ((Company *)Root)->LineOfDuty(Root); rt_kprintf("#############################################################################"); ((Company *)Comp)->Remove(Comp, Comp1); rt_kprintf(" 公司结构图:\n"); ((Company *)Root)->Display(Root, 1); rt_kprintf(" 职责:\n"); ((Company *)Root)->LineOfDuty(Root); rt_kprintf("#############################################################################"); ((Company *)Comp)->Remove(Comp, Comp2); rt_kprintf(" 公司结构图:\n"); ((Company *)Root)->Display(Root, 1); rt_kprintf(" 职责:\n"); ((Company *)Root)->LineOfDuty(Root); rt_kprintf("#############################################################################"); ((Company *)Root)->Remove(Root, Comp); rt_kprintf(" 公司结构图:\n"); ((Company *)Root)->Display(Root, 1); rt_kprintf(" 职责:\n"); ((Company *)Root)->LineOfDuty(Root); rt_kprintf("#############################################################################"); ((Company *)Comp)->Delete(Comp); ((Company *)CompHR)->Delete(CompHR); ((Company *)CompFD)->Delete(CompFD); ((Company *)Comp1)->Delete(Comp1); ((Company *)Comp1HR)->Delete(Comp1HR); ((Company *)Comp1FD)->Delete(Comp1FD); ((Company *)Comp2)->Delete(Comp2); ((Company *)Comp2HR)->Delete(Comp2HR); ((Company *)Comp2FD)->Delete(Comp2FD); ((Company *)Root)->Delete(Root); ((Company *)RootHR)->Delete(RootHR); ((Company *)RootFD)->Delete(RootFD); }FINSH_FUNCTION_EXPORT(Composite, Composite Modle);组合模式是用同一模板来创建层次不同的对像,但每个对像的数据处理方法基本相同,组合后可从根上遍历到每一个叶点,WINDOWS资源浏览器就是典型的组合模式!
设计模式-桥接形式
Java多线程设计模式之线程池形式
三路归并能做而两路合并不能做的事
数据驱动测试(1) 开篇
Maven依赖治理的规则
sonarqube 札记1
sonarqube札记之-代码注释行的量度
捕杀JDialog的关闭事件
怎么带好自已的团队
【转】【外刊IT评述】企业自杀行为:重