您的位置:首页 > 编程语言 > C语言/C++

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

2012-10-18 15:39 627 查看
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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: