C语言实现《大话设计模式》中的观察者模式中的委托例程

C语言实现《大话设计模式》中的观察者模式中的委托例程

 1. #ifndef __ENTRUSTOBSERVER_H__ 
2. #define __ENTRUSTOBSERVER_H__ 
3. #include "rtthread.h" 
4. #include "finsh.h" 
5. //根据类名和类里面项的名,获得类的入口句柄 
6. #define ClassEntry(node, type, member) \ 
7.     ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member))) 
8. //LIST数组 
9. typedef struct _List List; 
10. struct _List 
11. { 
12.     void **pListPointArray;                         //LIST数组指针 
13.     int Total;                                      //元素个数 
14.     void (*Add)(List *pList, void *pListPoint);     //添加 
15.     void (*Remove)(List *pList, void *pListPoint);  //移除 
16.     void (*Delete)(void *pList);                    //析构 
17. }; 
18. //List类的析构函数 
19. static void ListDelete(void *pList) 
20. { 
21.     if(((List *)pList)->pListPointArray != RT_NULL)     //先释放指针数组 
22.     { 
23.         rt_free(((List *)pList)->pListPointArray); 
24.     } 
25.     rt_free(pList);                                     //再释放整个List类 
26. } 
27. //元素增加函数 
28. static void ListAdd(List *pList, void *pListPoint) 
29. { 
30.     void **tListPointArray = rt_malloc(sizeof(int *) * (pList->Total + 1));     //申请比原来大一个存储单元的内存 
31.     int pListIndex; 
32.     for(pListIndex = 0; pListIndex < pList->Total; pListIndex++)        //拷贝 
33.     { 
34.         if(pList->pListPointArray[pListIndex] == pListPoint)                 //判断,如果有相同的元素存在 
35.         {    
36.             rt_free(tListPointArray);                                        //释放现申请的内存 
37.             return;                                                     //返回 
38.         } 
39.         tListPointArray[pListIndex] = pList->pListPointArray[pListIndex];         //拷贝 
40.     } 
41.     tListPointArray[pList->Total] = pListPoint;                              //将添加的元素放到最后一个存储单元中 
42.     pList->Total += 1;                                                  //总数加1 
43.     if(pList->pListPointArray != RT_NULL) rt_free(pList->pListPointArray);                      //释放原来的内存 
44.     pList->pListPointArray = tListPointArray;                                            //将新的句柄替换原句柄 
45. } 
46. //元素移除函数 
47. static void ListRemove(List *pList, void *pListPoint) 
48. { 
49.     int pListIndex, tListIndex; 
50.     void **tListPointArray; 
51.     void **FreePointArray; 
52.     void **SavePointArray; 
53.     if(pList->Total == 0) return;                                       //总数为0时退出 
54.     tListPointArray = rt_malloc(sizeof(int) * (pList->Total - 1));    //申请比原来小一个存储单元的内存 
55.     FreePointArray = tListPointArray;                                  //将刚申请的内存空间作为默认的释放空间 
56.     SavePointArray = pList->pListPointArray;                           //将已有的内存空间作为默认的存储空间 
57.     for(pListIndex = 0, tListIndex= 0; pListIndex < pList->Total; pListIndex++) //查找移除点 
58.     { 
59.         if(pList->pListPointArray[pListIndex] == pListPoint)         //当前点是移除点 
60.         { 
61.             FreePointArray = pList->pListPointArray;            //改变释放内存指针 
62.             SavePointArray = tListPointArray;                   //改变保留内存指针 
63.             continue;                                           //结束本次循环 
64.         } 
65.         if(tListIndex < (pList->Total -1))                      //如果当前点不是移除点,拷贝序号小于总量减1 
66.         { 
67.             tListPointArray[tListIndex] = pList->pListPointArray[pListIndex];     //拷贝 
68.             tListIndex++;                                               //拷贝序号加1 
69.         } 
70.     } 
71.     pList->Total = (SavePointArray == tListPointArray) ? pList->Total - 1 : pList->Total;   //根据保留的内存块改变总数的值 
72.     if(FreePointArray != RT_NULL) rt_free(FreePointArray);        //释放该释放的不用的内存块 
73.     pList->pListPointArray = SavePointArray; //保留该保留的 
74. } 
75. //List构造函数 
76. static List *ListCreate(void) 
77. { 
78.     List *pList = (List *)rt_malloc(sizeof(List)); 
79.     pList->Total = 0; 
80.     pList->pListPointArray = RT_NULL; 
81.     pList->Add = ListAdd; 
82.     pList->Remove = ListRemove; 
83.     pList->Delete = ListDelete; 
84.     return pList; 
85. } 
86. //委托类 
87. typedef void (*Event)(void *); 
88. typedef struct _Entrust Entrust; 
89. struct _Entrust 
90. { 
91.     List *FunArray; 
92.     void (*Add)(void *pEntrust, void *pObject); 
93.     void (*Remove)(void *pEntrust, void *pObject); 
94.     void (*Update)(void *pEntrust); 
95.     void (*Delete)(void *pEntrust); 
96. }; 
97. static void EntrustAdd(void *pEntrust, void *pFun) 
98. { 
99.     List *pList = ((Entrust *)pEntrust)->FunArray; 
100.     pList->Add(pList, pFun); 
101. } 
102. static void EntrustRemove(void *pEntrust, void *pFun) 
103. { 
104.     List *pList = ((Entrust *)pEntrust)->FunArray; 
105.     pList->Remove(pList, pFun); 
106. } 
107. static void EntrustUpdate(void *pEntrust) 
108. { 
109.     List *pListFun = ((Entrust *)pEntrust)->FunArray; 
110.     int i; 
111.     int FunAddress; 
112.     if(pListFun->Total == 0) return; 
113.     for(i = 0; i < pListFun->Total; i++) 
114.     { 
115.         FunAddress = (int)(*(pListFun->pListPointArray + i)); 
116.         //先将整型变量转换成一个整形指针,再将该指针指向的内容转换成Event函数指针 
117.         (*(Event)(*(int *)FunAddress))(pListFun->pListPointArray[i]); 
118.     } 
119. } 
120. static void EntrustDelete(void *pEntrust) 
121. { 
122.     List *pList = ((Entrust *)pEntrust)->FunArray; 
123.     pList->Delete(pList); 
124.     rt_free(pEntrust); 
125. } 
126. static Entrust *EntrustCreate(rt_size_t Size) 
127. { 
128.     Entrust *pEntrust = (Entrust *)rt_malloc(Size); 
129.     pEntrust->FunArray = (List *)ListCreate(); 
130.     pEntrust->Add = EntrustAdd; 
131.     pEntrust->Remove = EntrustRemove; 
132.     pEntrust->Update = EntrustUpdate; 
133.     pEntrust->Delete = EntrustDelete; 
134.     return pEntrust; 
135. } 
136. //具体通知者 
137. //通知者:老板 
138. typedef struct _Boss Boss; 
139. struct _Boss 
140. { 
141.     Entrust *pEntrust;      //添加一个委托类 
142.     char *Action; 
143.     char *(*GetSubjectState)(void *pBoss); 
144.     void (*SetSubjectState)(void *pBoss, char *pBossState); 
145.     void (*Notify)(void *pBoss); 
146.     void (*Delete)(void *pBoss); 
147. }; 
148. static char *BossGetSubjectState(void *pBoss) 
149. { 
150.     return ((Boss *)pBoss)->Action; 
151. } 
152. static void BossSetSubjectState(void *pBoss, char *pBossState) 
153. { 
154.     ((Boss *)pBoss)->Action = pBossState; 
155. } 
156. static void BossNotify(void *pBoss) 
157. { 
158.     Entrust *pEntrust = ((Boss *)pBoss)->pEntrust; 
159.     pEntrust->Update(pEntrust); 
160. } 
161. static void BossDelete(void *pBoss) 
162. { 
163.     Entrust *pEntrust = ((Boss *)pBoss)->pEntrust; 
164.     pEntrust->Delete(pEntrust); 
165.     rt_free(pBoss); 
166. } 
167. static Boss *BossCreate(rt_size_t Size) 
168. { 
169.     Boss *pBoss = (Boss *)rt_malloc(Size); 
170.     pBoss->pEntrust = EntrustCreate(sizeof(Entrust)); 
171.     //重写函数 
172.     pBoss->GetSubjectState = BossGetSubjectState; 
173.     pBoss->SetSubjectState = BossSetSubjectState; 
174.     pBoss->Notify = BossNotify; 
175.     pBoss->Delete = BossDelete; 
176.     return pBoss; 
177. } 
178. //具体观察者 
179. //看股票的同事 
180. typedef struct _StockObserver StockObserver; 
181. struct _StockObserver 
182. { 
183.     char *Name; 
184.     Boss *pSub; 
185.     void (*CloseStock)(void *pObserver); 
186.     void (*Delete)(void *pObserver); 
187. }; 
188. static void CloseStock(void *pCloseStock) 
189. { 
190.     StockObserver *pStockObserver = ClassEntry(pCloseStock, StockObserver, CloseStock); 
191.     Boss *pSub = pStockObserver->pSub; 
192.     rt_kprintf(" %s,%s关闭股票行情,继续工作\n", pSub->GetSubjectState(pSub), pStockObserver->Name); 
193. } 
194. static void StockObserverDelete(void *pStockObserver) 
195. { 
196.     rt_free(pStockObserver); 
197. } 
198. static StockObserver *StockObserverCreate(char *Name, void *pSub, rt_size_t Size) 
199. { 
200.     StockObserver *pStockObserver = (StockObserver *)rt_malloc(Size); 
201.     pStockObserver->Name = Name; 
202.     pStockObserver->pSub = pSub; 
203.     pStockObserver->CloseStock = CloseStock; 
204.     pStockObserver->Delete = StockObserverDelete; 
205.     return pStockObserver; 
206. } 
207. //看NBA的同事 
208. typedef struct _NBAObserver NBAObserver; 
209. struct _NBAObserver 
210. { 
211.     char *Name; 
212.     Boss *pSub; 
213.     void (*CloseNBA)(void *pObserver); 
214.     void (*Delete)(void *pObserver);   
215. }; 
216. static void CloseNBA(void *pCloseNBA) 
217. { 
218.     NBAObserver *pNBAObserver = ClassEntry(pCloseNBA, NBAObserver, CloseNBA); 
219.     Boss *pSub = pNBAObserver->pSub; 
220.     rt_kprintf(" %s,%s关闭NBA转播,继续工作\n", pSub->GetSubjectState(pSub), pNBAObserver->Name); 
221. } 
222. static void NBAObserverDelete(void *pNBAObserver) 
223. { 
224.     rt_free(pNBAObserver); 
225. } 
226. static NBAObserver *NBAObserverCreate(char *Name, void *pSub, rt_size_t Size) 
227. { 
228.     NBAObserver *pNBAObserver = (NBAObserver *)rt_malloc(Size); 
229.     pNBAObserver->Name = Name; 
230.     pNBAObserver->pSub = pSub; 
231.     pNBAObserver->CloseNBA = CloseNBA; 
232.     pNBAObserver->Delete = NBAObserverDelete; 
233.     return pNBAObserver; 
234. } 
235.  
236. #endif 
237.  
238.  
239.  
240. #include "EntrustObserver.h" 
241. //客户端 
242. void EntrustObs(void) 
243. { 
244.     Boss *huhasan = BossCreate(sizeof(Boss)); 
245.     StockObserver *tongshi1 = StockObserverCreate("魏关姹", huhasan, sizeof(StockObserver)); 
246.     NBAObserver *tongshi2 = NBAObserverCreate("易管查", huhasan, sizeof(NBAObserver)); 
247.     //在委托里添加事件功能 www.2cto.com
248.     huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi1->CloseStock)); 
249.     huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi2->CloseNBA)); 
250.     //改变通知者状态 
251.     huhasan->SetSubjectState(huhasan, "我胡汉三回来啦"); 
252.     //通知者通知 
253.     huhasan->Notify(huhasan); 
254.      
255.     huhasan->Delete(huhasan); 
256.     tongshi1->Delete(tongshi1); 
257.     tongshi2->Delete(tongshi2); 
258. } 
259. FINSH_FUNCTION_EXPORT(EntrustObs, Entrust Observer Modle);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值