1. #include<iostream>
  2. #include<vector>
  3.  
  4. //get namespace related stuff
  5. using std::cin;
  6. using std::cout;
  7. using std::endl;
  8. using std::flush;
  9. using std::string;
  10. using std::vector;
  11.  
  12. //struct Observer, modeled after java.utils.Observer
  13. struct Observer
  14. /*
  15. * AK: This could be a template (C++) or generic (Java 5),
  16. * however the original Smalltalk MVC didn't do that.
  17. */
  18. {
  19. //update
  20. virtual void update(void*)=;
  21. };
  22.  
  23. //struct Observable, modeled after java.utils.Observable
  24. struct Observable
  25. {
  26. //observers
  27. vector<Observer*>observers;
  28.  
  29. //addObserver
  30. void addObserver(Observer*a){observers.push_back(a);}
  31.  
  32. //notifyObservers
  33. void notifyObservers()
  34. {
  35. for (vector<Observer*>::const_iterator observer_iterator=observers.begin();observer_iterator!=observers.end();observer_iterator++)
  36. (*observer_iterator)->update(this);
  37. }
  38.  
  39. /*
  40. AK: If you had a method which takes an extra "ARG" argument like this
  41. notifyObservers(void* ARG), you can pass that arg to each Observer via
  42. the call (*observer_iterator)->update(this,ARG);
  43.  
  44. This can significantly increase your View's reusablity down the track.
  45. I'll explain why below in the View.
  46. */
  47.  
  48. };
  49.  
  50. //struct Model, contains string-data and methods to set and get the data
  51. struct Model:Observable
  52. {
  53. //data members title_caption, version_caption, credits_caption
  54. string title_caption;
  55. string version_caption;
  56. string credits_caption;
  57.  
  58. //data members title, version, credits
  59. string title;
  60. string version;
  61. string credits;
  62.  
  63. //constructor
  64. Model() :
  65. title_caption("Title: "),
  66. version_caption("Version: "),
  67. credits_caption("Credits: "),
  68. title("Simple Model-View-Controller Implementation"),
  69. version("0.2"),
  70. credits("(put your name here)")
  71. { }
  72.  
  73. //getCredits_Caption, getTitle_Caption, getVersion_Caption
  74. string getCredits_Caption(){return credits_caption;}
  75. string getTitle_Caption(){return title_caption;}
  76. string getVersion_Caption(){return version_caption;}
  77.  
  78. //getCredits, getTitle, getVersion
  79. string getCredits(){return credits;}
  80. string getTitle(){return title;}
  81. string getVersion(){return version;}
  82.  
  83. //setCredits, setTitle, setVersion
  84. void setCredits(string a){credits=a;notifyObservers();}
  85. void setTitle(string a){title=a;notifyObservers();}
  86. void setVersion(string a){version=a;notifyObservers();}
  87. /*
  88. * AK notifyObservers(a) for credit, title and version.
  89. * All as per discussion in View and Observer *
  90. */
  91. };
  92.  
  93. /*
  94. AK:
  95. Great stuff ;-) This satisfies a major principle of the MVC
  96. architecture, the separation of model and view.
  97.  
  98. The model now has NO View material in it, this model can now be used in
  99. other applications.
  100. You can use it with command line apps (batch, testing, reports, ...),
  101. web, gui, etc.
  102.  
  103. Mind you "MVC with Passive Model" is a variation of MVC where the model
  104. doesn't get even involved with the Observer pattern.
  105.  
  106. In that case the Controller would trigger a model update *and it* could
  107. also supply the latest info do the Views. This is a fairly common MVC
  108. variation, especially with we apps.
  109. */
  110.  
  111. //struct TitleView, specialized Observer
  112. struct TitleView:Observer
  113. {
  114. /*
  115. * AK:
  116. * I like to get a reference to the model via a constructor to avoid
  117. * a static_cast in update and to avoid creating zombie objects.
  118. *
  119. * A zombie object is instantiated but is unusable because it
  120. * is missing vital elements. Dangerous. Getting model via the
  121. * constructor solves this problem.
  122.  
  123. Model model;
  124. // Cons.
  125. TitleView (Model* m) ....
  126.  
  127. RE-USABILITY.
  128. Some views are better off working with the full Model, yet others are
  129. better off being dumber.
  130.  
  131. I like to have two kinds of Views. Those that work with full Model (A)
  132. and those that only work with a limited more abstract data type (B).
  133.  
  134. Type A.
  135. Complex application specific views are better off getting the full
  136. model, they can then just pick and choose what they need from the full
  137. model without missing something all the time. Convenient.
  138.  
  139. Type B.
  140. These only require abstract or generic data types.
  141.  
  142. Consider a PieChartView, it doesn't really need to know about the full
  143. Model of a particular application, it can get by with just float
  144. *values[] or vector<float>;
  145.  
  146. By avoiding Model you can then reuse PieChartView in other applications
  147. with different models.
  148.  
  149. For this to be possible you must use the 2 argument version of
  150. notifyObservers. See comments on Observer class.
  151.  
  152. See my Java example NameView. That view only knows about a String, not
  153. the full Model.
  154. */
  155.  
  156. //update
  157. void update(void*a)
  158. /*
  159. *AK:void update(void*a, void*arg) is often better. As per discussion
  160. above.
  161. */
  162. {
  163. cout<<static_cast<Model*>(a)->getTitle_Caption();
  164. cout<<static_cast<Model*>(a)->getTitle();
  165. cout<<endl;
  166. }
  167. };
  168.  
  169. //struct VersionView, specialized Observer
  170. struct VersionView:Observer
  171. {
  172.  
  173. //update
  174. void update(void*a)
  175. {
  176. cout<<static_cast<Model*>(a)->getVersion_Caption();
  177. cout<<static_cast<Model*>(a)->getVersion();
  178. cout<<endl;
  179. }
  180. };
  181.  
  182. //struct CreditsView, specialized Observer
  183. struct CreditsView:Observer
  184. {
  185.  
  186. //update
  187. void update(void*a)
  188. {
  189. cout<<static_cast<Model*>(a)->getCredits_Caption();
  190. cout<<static_cast<Model*>(a)->getCredits();
  191. cout<<endl;
  192. }
  193. };
  194.  
  195. //struct Views, pack all Observers together in yet another Observer
  196. struct Views:Observer
  197. {
  198. //data members titleview, versionview, creditsview
  199. TitleView titleview;
  200. VersionView versionview;
  201. CreditsView creditsview;
  202. /*
  203. * AK:
  204. * Views are often hierarchical and composed of other Views. See
  205. Composite pattern.
  206. * vector<View*> views;
  207. *
  208. * Views often manage (create and own) a Controller.
  209. *
  210. * Views may include their own Controller code (Delegate).
  211. *
  212. */
  213. //setModel
  214. void setModel(Observable&a)
  215. {
  216. a.addObserver(&titleview);
  217. a.addObserver(&versionview);
  218. a.addObserver(&creditsview);
  219. a.addObserver(this);
  220. }
  221.  
  222. //update
  223. void update(void*a)
  224. {
  225. cout<<"_____________________________";
  226. cout<<"\nType t to edit Title, ";
  227. cout<<"v to edit Version, ";
  228. cout<<"c to edit Credits. ";
  229. cout<<"Type q to quit./n>>";
  230. }
  231. };
  232.  
  233. //struct Controller, wait for keystroke and change Model
  234. struct Controller
  235. /*
  236. * AK: Controller can also be an Observer.
  237. *
  238. * There is much to say about Controller but IMHO we should defer
  239. * that to another version.
  240. */
  241. {
  242. //data member model
  243. Model*model;
  244.  
  245. //setModel
  246. void setModel(Model&a){model=&a;}
  247.  
  248. //MessageLoop
  249. void MessageLoop()
  250. {
  251. char c=' ';
  252. string s;
  253. while(c!='q')
  254. {
  255. cin>>c;
  256. cin.ignore(,'\n');
  257. cin.clear();
  258. switch(c)
  259. {
  260. case 'c':
  261. case 't':
  262. case 'v':
  263. getline(cin,s);
  264. break;
  265. }
  266. switch(c)
  267. {
  268. case 'c':model->setCredits(s);break;
  269. case 't':model->setTitle(s);break;
  270. case 'v':model->setVersion(s);break;
  271. }
  272. }
  273. }
  274. };
  275.  
  276. //struct Application, get Model, Views and Controller together
  277. struct Application
  278. {
  279.  
  280. //data member model
  281. Model model;
  282.  
  283. //data member views
  284. Views views;
  285.  
  286. //data member controller
  287. Controller controller;
  288.  
  289. //constructor
  290. Application()
  291. {
  292. views.setModel(model);
  293. controller.setModel(model);
  294. model.notifyObservers();
  295. }
  296.  
  297. //run
  298. void run(){controller.MessageLoop();}
  299. };
  300.  
  301. //main
  302. int main()
  303. {
  304. Application().run();
  305. return ;
  306. }

一个很小的C++写的MVC的例子的更多相关文章

  1. 【生产问题】记还原一个很小的BAK文件,但却花了很长时间,分析过程

    [生产问题]还原一个很小的BAK文件,但却花了很长时间? 关键词:备份时事务日志太大会发生什么?还原时,事务日志太大会怎么办? 1.前提: [1.1]原库数据已经丢失,只有这个bak了 [1.2]ba ...

  2. 【mysql】一个很小但很影响速度的地方

    如果要插入一大批数据,千万不要一条一条的execute, commit.而应该是先全部execute,最后统一commit!!! 千万注意,时间差距还是很大的!! 正确示范:快 ): sql = &q ...

  3. jquery学习心得:一个很好的css和js函数调用的例子

    统一目录下的资源结构图: <html><head> <link rel="stylesheet" href="gallery.css&quo ...

  4. 手把手教你写一个RN小程序!

    时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现 ...

  5. 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)

    引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...

  6. 很小的一个函数执行时间调试器Timer

    对于函数的执行性能(这里主要考虑执行时间,所耗内存暂不考虑),这里写了一个简单的类Timer,用于量化函数执行所耗时间. 整体思路很简单,就是new Date()的时间差值.我仅仅了做了一层简单的封装 ...

  7. 「小程序JAVA实战」 小程序手写属于自己的第一个demo(六)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-06/ 自己尝试的写一个小demo,用到自定义样式,自定义底部导航,页面之间的跳转等小功能.官方文档 ...

  8. 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序

    分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图.      1.首先建立一个数 ...

  9. MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。

    MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得. 之前的项目比较简单,多是用JSP .Servlet + JDBC 直接搞定,在项目中尝试用 Strut ...

随机推荐

  1. visual studio中使用vim快捷键

    vsvim下载链接: https://marketplace.visualstudio.com/items?itemName=JaredParMSFT.VsVim 下载,关闭visual studio ...

  2. 对数组内容使用了json_encode返回汉字内容返回了空值

    如果使用json_encode对数组进行转成JSON字符串时候,发现汉字的全部为空,这样可以说明的一点是你的页面上用的一定不是UTF8编码,在PHP手册中对json_encode中待编码的值已经说明所 ...

  3. linux批量检测服务器能否ping通和硬盘容量状态并抛出报警的一个脚本-附详细解释

    有一些linux基础,最近刚开始学shell,参考了阿良老师的一个监测服务器硬盘状态的脚本,自己进行了一些扩展,今天比较晚了,后边会把注释放上来,感觉脚本还很不完善,希望大家一起探讨一下,共同学习 2 ...

  4. [AI开发]基于DeepStream的视频结构化解决方案

    视频结构化的定义 利用深度学习技术实时分析视频中有价值的内容,并输出结构化数据.相比数据库中每条结构化数据记录,视频.图片.音频等属于非结构化数据,计算机程序不能直接识别非结构化数据,因此需要先将这些 ...

  5. Java 新手学习日记一

    Java 基础知识点掌握: 数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间.内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此 ...

  6. 【02】一个实现h5的拖放的整个过程-魔芋

    [02]拖放的整个过程-魔芋   01,创建2个元素,一个为拖放元素dragEle,一个是存放的元素targetEle.添加一些样式.   <div class="dragEle&qu ...

  7. MySQL语句之or和and多条件查询

    在where中可以包含任意数目的and和or操作符,需要注意的是在没有任何其他符号的时候,例如括号,AND的优先级高于OR,因此,当两者一起使用时,先运算AND两边的条件表达式,再运算OR两边的条件表 ...

  8. 【Ajax 2】封装Ajax的核心对象:XMLHttpRequest对象

    导读:AJAX利用一个构建到所有现代浏览器内部的对象-XMLHttpRequest-来实现发送和接收HTTP请求与响应信息.那么,XMLHttpRequest对象是怎么创建和封装的呢? 一.简介 1. ...

  9. LibreOJ2302 - 「NOI2017」整数

    Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...

  10. docker容器的导入导出

    导出容器docker export 导出容器快照到本地文件$ sudo docker ps -aCONTAINER ID        IMAGE               COMMAND      ...