发布时间: 2012-06-20 20:37:21 作者: rapoo
C语言实现《大话设计模式》中的观察者模式例程#ifndef __OBSERVER_H__#define __OBSERVER_H__#include "rtthread.h"#include "finsh.h"//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 struct _Subject Subject;typedef struct _Observer Observer;typedef struct _Boss Boss;//抽像观察者struct _Observer{ char *Name; Subject *pSub; void (*Update)(void *pObserver); void (*Delete)(void *pObserver);};static void ObserverDelete(void *pObserver){ rt_free(pObserver);}Observer *ObserverCreate(char *Name, void *pSub, rt_size_t Size){ Observer *pObserver = (Observer *)rt_malloc(Size); pObserver->Name = Name; pObserver->pSub = pSub; pObserver->Delete = ObserverDelete; return pObserver;}//抽像通知者接口struct _Subject{ char *(*GetSubjectState)(void *pSubject); void (*SetSubjectState)(void *pSubject, char *pSubjectState); void (*Attach)(void *pSubject, void *pObserver); void (*Detach)(void *pSubject, void *pObserver); void (*Notify)(void *pSubject); void (*Delete)(void *pSubject);};//具体观察者//看股票的同事typedef struct _StockObserver StockObserver;struct _StockObserver{ Observer mObserver; };static void StockObserverUpdata(void *pStockObserver){ Subject *pSub = ((Observer *)pStockObserver)->pSub; // pSub->GetSubjectState(pSub); // pSub->GetSubjectState(pSub); // char *State = *pSub->GetSubjectState(pSub); rt_kprintf(" %s,%s关闭股票行情,继续工作\n" , pSub->GetSubjectState(pSub) , ((Observer *)pStockObserver)->Name);}StockObserver *StockObserverCreate(char *Name, void *pSub, rt_size_t Size){ StockObserver *pStockObserver = (StockObserver *)ObserverCreate(Name, pSub, Size); ((Observer *)pStockObserver)->Update = StockObserverUpdata; return pStockObserver;}//看NBA的同事typedef struct _NBAObserver NBAObserver;struct _NBAObserver{ Observer mObserver; };static void NBAObserverUpdata(void *pNBAObserver){ Subject *pSub = ((Observer *)pNBAObserver)->pSub; rt_kprintf(" %s,%s关闭NBA转播,继续工作\n", pSub->GetSubjectState(pSub), ((Observer *)pNBAObserver)->Name);}NBAObserver *NBAObserverCreate(char *Name, void *pSub, rt_size_t Size){ NBAObserver *pNBAObserver = (NBAObserver *)ObserverCreate(Name, pSub, Size); ((Observer *)pNBAObserver)->Update = NBAObserverUpdata; return pNBAObserver;}static void SubjectDelete(void *pSubject){ rt_free(pSubject);}Subject *SubjectCreate(rt_size_t Size){ Subject *pSubject = (Subject *)rt_malloc(Size); pSubject->Delete = SubjectDelete; return pSubject;}//具体通知者//通知者:老板struct _Boss{ Subject mSubject; List *Observers; char *Action;};static char *BossGetSubjectState(void *pBoss){ return ((Boss *)pBoss)->Action;}static void BossSetSubjectState(void *pBoss, char *pBossState){ ((Boss *)pBoss)->Action = pBossState;}static void BossAttach(void *pBoss, void *pObserver){ List *pList = ((Boss *)pBoss)->Observers; pList->Add(pList, pObserver);}static void BossDetach(void *pBoss, void *pObserver){ List *pList = ((Boss *)pBoss)->Observers; pList->Remove(pList, pObserver);}static void BossNotify(void *pBoss){ List *pList = ((Boss *)pBoss)->Observers; int i; for(i = 0; i < pList->Total; i++) { ((Observer *)(pList->pListPointArray[i]))->Update(((Observer *)(pList->pListPointArray[i]))); }}static void BossDelete(void *pBoss){ ((Boss *)pBoss)->Observers->Delete(((Boss *)pBoss)->Observers); rt_free(pBoss);}Boss *BossCreate(rt_size_t Size){ Boss *pBoss = (Boss *)SubjectCreate(Size); pBoss->Observers = ListCreate(); //重写函数 ((Subject *)pBoss)->GetSubjectState = BossGetSubjectState; ((Subject *)pBoss)->SetSubjectState = BossSetSubjectState; ((Subject *)pBoss)->Attach = BossAttach; ((Subject *)pBoss)->Detach = BossDetach; ((Subject *)pBoss)->Notify = BossNotify; ((Subject *)pBoss)->Delete = BossDelete; return pBoss;}#endif#include "Observer.h"//客户端void ObserverModel(void){ Boss *huhasan = BossCreate(sizeof(Boss)); StockObserver *tongshi1 = StockObserverCreate("魏关姹", huhasan, sizeof(StockObserver)); NBAObserver *tongshi2 = NBAObserverCreate("易管查", huhasan, sizeof(NBAObserver)); ((Subject *)huhasan)->Attach(huhasan, tongshi1); ((Subject *)huhasan)->Attach(huhasan, tongshi2); ((Subject *)huhasan)->SetSubjectState(huhasan, "我胡汉三回来啦"); ((Subject *)huhasan)->Notify(huhasan); ((Subject *)huhasan)->Delete(huhasan); ((Observer *)tongshi1)->Delete(tongshi1); ((Observer *)tongshi2)->Delete(tongshi2);}FINSH_FUNCTION_EXPORT(ObserverModel, Observer Modle);观察者模式是抽像通知者和观察者,达到具体通知者跟具体观察者没有偶合。能达到不管是切换通知者,或者是切换观察者,都不会去操作其它的类!
设计模式-桥接形式
Java多线程设计模式之线程池形式
三路归并能做而两路合并不能做的事
数据驱动测试(1) 开篇
Maven依赖治理的规则
sonarqube 札记1
sonarqube札记之-代码注释行的量度
捕杀JDialog的关闭事件
怎么带好自已的团队
【转】【外刊IT评述】企业自杀行为:重