程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言實現《大話設計模式》中的觀察者模式中的委托例程

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); 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved