C语言实现《大话设计模式》中的观察者模式中的委托例程#ifndef __ENTRUSTOBSERVER_H__#define __ENTRUSTOBSERVER_H__#include "rtthread.h"#include "finsh.h"//根据类名和类里面项的名,获得类的入口句柄#define ClassEntry(node, type, member) \ ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))//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构造函数static 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 void (*Event)(void *);typedef struct _Entrust Entrust;struct _Entrust{ List *FunArray; void (*Add)(void *pEntrust, void *pObject); void (*Remove)(void *pEntrust, void *pObject); void (*Update)(void *pEntrust); void (*Delete)(void *pEntrust);};static void EntrustAdd(void *pEntrust, void *pFun){ List *pList = ((Entrust *)pEntrust)->FunArray; pList->Add(pList, pFun);}static void EntrustRemove(void *pEntrust, void *pFun){ List *pList = ((Entrust *)pEntrust)->FunArray; pList->Remove(pList, pFun);}static void EntrustUpdate(void *pEntrust){ List *pListFun = ((Entrust *)pEntrust)->FunArray; int i; int FunAddress; if(pListFun->Total == 0) return; for(i = 0; i < pListFun->Total; i++) { FunAddress = (int)(*(pListFun->pListPointArray + i)); //先将整型变量转换成一个整形指针,再将该指针指向的内容转换成Event函数指针 (*(Event)(*(int *)FunAddress))(pListFun->pListPointArray[i]); }}static void EntrustDelete(void *pEntrust){ List *pList = ((Entrust *)pEntrust)->FunArray; pList->Delete(pList); rt_free(pEntrust);}static Entrust *EntrustCreate(rt_size_t Size){ Entrust *pEntrust = (Entrust *)rt_malloc(Size); pEntrust->FunArray = (List *)ListCreate(); pEntrust->Add = EntrustAdd; pEntrust->Remove = EntrustRemove; pEntrust->Update = EntrustUpdate; pEntrust->Delete = EntrustDelete; return pEntrust;}//具体通知者//通知者:老板typedef struct _Boss Boss;struct _Boss{ Entrust *pEntrust; //添加一个委托类 char *Action; char *(*GetSubjectState)(void *pBoss); void (*SetSubjectState)(void *pBoss, char *pBossState); void (*Notify)(void *pBoss); void (*Delete)(void *pBoss);};static char *BossGetSubjectState(void *pBoss){ return ((Boss *)pBoss)->Action;}static void BossSetSubjectState(void *pBoss, char *pBossState){ ((Boss *)pBoss)->Action = pBossState;}static void BossNotify(void *pBoss){ Entrust *pEntrust = ((Boss *)pBoss)->pEntrust; pEntrust->Update(pEntrust);}static void BossDelete(void *pBoss){ Entrust *pEntrust = ((Boss *)pBoss)->pEntrust; pEntrust->Delete(pEntrust); rt_free(pBoss);}static Boss *BossCreate(rt_size_t Size){ Boss *pBoss = (Boss *)rt_malloc(Size); pBoss->pEntrust = EntrustCreate(sizeof(Entrust)); //重写函数 pBoss->GetSubjectState = BossGetSubjectState; pBoss->SetSubjectState = BossSetSubjectState; pBoss->Notify = BossNotify; pBoss->Delete = BossDelete; return pBoss;}//具体观察者//看股票的同事typedef struct _StockObserver StockObserver;struct _StockObserver{ char *Name; Boss *pSub; void (*CloseStock)(void *pObserver); void (*Delete)(void *pObserver);};static void CloseStock(void *pCloseStock){ StockObserver *pStockObserver = ClassEntry(pCloseStock, StockObserver, CloseStock); Boss *pSub = pStockObserver->pSub; rt_kprintf(" %s,%s关闭股票行情,继续工作\n", pSub->GetSubjectState(pSub), pStockObserver->Name);}static void StockObserverDelete(void *pStockObserver){ rt_free(pStockObserver);}static StockObserver *StockObserverCreate(char *Name, void *pSub, rt_size_t Size){ StockObserver *pStockObserver = (StockObserver *)rt_malloc(Size); pStockObserver->Name = Name; pStockObserver->pSub = pSub; pStockObserver->CloseStock = CloseStock; pStockObserver->Delete = StockObserverDelete; return pStockObserver;}//看NBA的同事typedef struct _NBAObserver NBAObserver;struct _NBAObserver{ char *Name; Boss *pSub; void (*CloseNBA)(void *pObserver); void (*Delete)(void *pObserver); };static void CloseNBA(void *pCloseNBA){ NBAObserver *pNBAObserver = ClassEntry(pCloseNBA, NBAObserver, CloseNBA); Boss *pSub = pNBAObserver->pSub; rt_kprintf(" %s,%s关闭NBA转播,继续工作\n", pSub->GetSubjectState(pSub), pNBAObserver->Name);}static void NBAObserverDelete(void *pNBAObserver){ rt_free(pNBAObserver);}static NBAObserver *NBAObserverCreate(char *Name, void *pSub, rt_size_t Size){ NBAObserver *pNBAObserver = (NBAObserver *)rt_malloc(Size); pNBAObserver->Name = Name; pNBAObserver->pSub = pSub; pNBAObserver->CloseNBA = CloseNBA; pNBAObserver->Delete = NBAObserverDelete; return pNBAObserver;}#endif#include "EntrustObserver.h"//客户端void EntrustObs(void){ Boss *huhasan = BossCreate(sizeof(Boss)); StockObserver *tongshi1 = StockObserverCreate("魏关姹", huhasan, sizeof(StockObserver)); NBAObserver *tongshi2 = NBAObserverCreate("易管查", huhasan, sizeof(NBAObserver)); //在委托里添加事件功能 huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi1->CloseStock)); huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi2->CloseNBA)); //改变通知者状态 huhasan->SetSubjectState(huhasan, "我胡汉三回来啦"); //通知者通知 huhasan->Notify(huhasan); huhasan->Delete(huhasan); tongshi1->Delete(tongshi1); tongshi2->Delete(tongshi2);}FINSH_FUNCTION_EXPORT(EntrustObs, Entrust Observer Modle);