一个很小的C++写的MVC的例子
- #include<iostream>
- #include<vector>
- //get namespace related stuff
- using std::cin;
- using std::cout;
- using std::endl;
- using std::flush;
- using std::string;
- using std::vector;
- //struct Observer, modeled after java.utils.Observer
- struct Observer
- /*
- * AK: This could be a template (C++) or generic (Java 5),
- * however the original Smalltalk MVC didn't do that.
- */
- {
- //update
- virtual void update(void*)=;
- };
- //struct Observable, modeled after java.utils.Observable
- struct Observable
- {
- //observers
- vector<Observer*>observers;
- //addObserver
- void addObserver(Observer*a){observers.push_back(a);}
- //notifyObservers
- void notifyObservers()
- {
- for (vector<Observer*>::const_iterator observer_iterator=observers.begin();observer_iterator!=observers.end();observer_iterator++)
- (*observer_iterator)->update(this);
- }
- /*
- AK: If you had a method which takes an extra "ARG" argument like this
- notifyObservers(void* ARG), you can pass that arg to each Observer via
- the call (*observer_iterator)->update(this,ARG);
- This can significantly increase your View's reusablity down the track.
- I'll explain why below in the View.
- */
- };
- //struct Model, contains string-data and methods to set and get the data
- struct Model:Observable
- {
- //data members title_caption, version_caption, credits_caption
- string title_caption;
- string version_caption;
- string credits_caption;
- //data members title, version, credits
- string title;
- string version;
- string credits;
- //constructor
- Model() :
- title_caption("Title: "),
- version_caption("Version: "),
- credits_caption("Credits: "),
- title("Simple Model-View-Controller Implementation"),
- version("0.2"),
- credits("(put your name here)")
- { }
- //getCredits_Caption, getTitle_Caption, getVersion_Caption
- string getCredits_Caption(){return credits_caption;}
- string getTitle_Caption(){return title_caption;}
- string getVersion_Caption(){return version_caption;}
- //getCredits, getTitle, getVersion
- string getCredits(){return credits;}
- string getTitle(){return title;}
- string getVersion(){return version;}
- //setCredits, setTitle, setVersion
- void setCredits(string a){credits=a;notifyObservers();}
- void setTitle(string a){title=a;notifyObservers();}
- void setVersion(string a){version=a;notifyObservers();}
- /*
- * AK notifyObservers(a) for credit, title and version.
- * All as per discussion in View and Observer *
- */
- };
- /*
- AK:
- Great stuff ;-) This satisfies a major principle of the MVC
- architecture, the separation of model and view.
- The model now has NO View material in it, this model can now be used in
- other applications.
- You can use it with command line apps (batch, testing, reports, ...),
- web, gui, etc.
- Mind you "MVC with Passive Model" is a variation of MVC where the model
- doesn't get even involved with the Observer pattern.
- In that case the Controller would trigger a model update *and it* could
- also supply the latest info do the Views. This is a fairly common MVC
- variation, especially with we apps.
- */
- //struct TitleView, specialized Observer
- struct TitleView:Observer
- {
- /*
- * AK:
- * I like to get a reference to the model via a constructor to avoid
- * a static_cast in update and to avoid creating zombie objects.
- *
- * A zombie object is instantiated but is unusable because it
- * is missing vital elements. Dangerous. Getting model via the
- * constructor solves this problem.
- Model model;
- // Cons.
- TitleView (Model* m) ....
- RE-USABILITY.
- Some views are better off working with the full Model, yet others are
- better off being dumber.
- I like to have two kinds of Views. Those that work with full Model (A)
- and those that only work with a limited more abstract data type (B).
- Type A.
- Complex application specific views are better off getting the full
- model, they can then just pick and choose what they need from the full
- model without missing something all the time. Convenient.
- Type B.
- These only require abstract or generic data types.
- Consider a PieChartView, it doesn't really need to know about the full
- Model of a particular application, it can get by with just float
- *values[] or vector<float>;
- By avoiding Model you can then reuse PieChartView in other applications
- with different models.
- For this to be possible you must use the 2 argument version of
- notifyObservers. See comments on Observer class.
- See my Java example NameView. That view only knows about a String, not
- the full Model.
- */
- //update
- void update(void*a)
- /*
- *AK:void update(void*a, void*arg) is often better. As per discussion
- above.
- */
- {
- cout<<static_cast<Model*>(a)->getTitle_Caption();
- cout<<static_cast<Model*>(a)->getTitle();
- cout<<endl;
- }
- };
- //struct VersionView, specialized Observer
- struct VersionView:Observer
- {
- //update
- void update(void*a)
- {
- cout<<static_cast<Model*>(a)->getVersion_Caption();
- cout<<static_cast<Model*>(a)->getVersion();
- cout<<endl;
- }
- };
- //struct CreditsView, specialized Observer
- struct CreditsView:Observer
- {
- //update
- void update(void*a)
- {
- cout<<static_cast<Model*>(a)->getCredits_Caption();
- cout<<static_cast<Model*>(a)->getCredits();
- cout<<endl;
- }
- };
- //struct Views, pack all Observers together in yet another Observer
- struct Views:Observer
- {
- //data members titleview, versionview, creditsview
- TitleView titleview;
- VersionView versionview;
- CreditsView creditsview;
- /*
- * AK:
- * Views are often hierarchical and composed of other Views. See
- Composite pattern.
- * vector<View*> views;
- *
- * Views often manage (create and own) a Controller.
- *
- * Views may include their own Controller code (Delegate).
- *
- */
- //setModel
- void setModel(Observable&a)
- {
- a.addObserver(&titleview);
- a.addObserver(&versionview);
- a.addObserver(&creditsview);
- a.addObserver(this);
- }
- //update
- void update(void*a)
- {
- cout<<"_____________________________";
- cout<<"\nType t to edit Title, ";
- cout<<"v to edit Version, ";
- cout<<"c to edit Credits. ";
- cout<<"Type q to quit./n>>";
- }
- };
- //struct Controller, wait for keystroke and change Model
- struct Controller
- /*
- * AK: Controller can also be an Observer.
- *
- * There is much to say about Controller but IMHO we should defer
- * that to another version.
- */
- {
- //data member model
- Model*model;
- //setModel
- void setModel(Model&a){model=&a;}
- //MessageLoop
- void MessageLoop()
- {
- char c=' ';
- string s;
- while(c!='q')
- {
- cin>>c;
- cin.ignore(,'\n');
- cin.clear();
- switch(c)
- {
- case 'c':
- case 't':
- case 'v':
- getline(cin,s);
- break;
- }
- switch(c)
- {
- case 'c':model->setCredits(s);break;
- case 't':model->setTitle(s);break;
- case 'v':model->setVersion(s);break;
- }
- }
- }
- };
- //struct Application, get Model, Views and Controller together
- struct Application
- {
- //data member model
- Model model;
- //data member views
- Views views;
- //data member controller
- Controller controller;
- //constructor
- Application()
- {
- views.setModel(model);
- controller.setModel(model);
- model.notifyObservers();
- }
- //run
- void run(){controller.MessageLoop();}
- };
- //main
- int main()
- {
- Application().run();
- return ;
- }
一个很小的C++写的MVC的例子的更多相关文章
- 【生产问题】记还原一个很小的BAK文件,但却花了很长时间,分析过程
[生产问题]还原一个很小的BAK文件,但却花了很长时间? 关键词:备份时事务日志太大会发生什么?还原时,事务日志太大会怎么办? 1.前提: [1.1]原库数据已经丢失,只有这个bak了 [1.2]ba ...
- 【mysql】一个很小但很影响速度的地方
如果要插入一大批数据,千万不要一条一条的execute, commit.而应该是先全部execute,最后统一commit!!! 千万注意,时间差距还是很大的!! 正确示范:快 ): sql = &q ...
- jquery学习心得:一个很好的css和js函数调用的例子
统一目录下的资源结构图: <html><head> <link rel="stylesheet" href="gallery.css&quo ...
- 手把手教你写一个RN小程序!
时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现 ...
- 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)
引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...
- 很小的一个函数执行时间调试器Timer
对于函数的执行性能(这里主要考虑执行时间,所耗内存暂不考虑),这里写了一个简单的类Timer,用于量化函数执行所耗时间. 整体思路很简单,就是new Date()的时间差值.我仅仅了做了一层简单的封装 ...
- 「小程序JAVA实战」 小程序手写属于自己的第一个demo(六)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-06/ 自己尝试的写一个小demo,用到自定义样式,自定义底部导航,页面之间的跳转等小功能.官方文档 ...
- 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序
分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图. 1.首先建立一个数 ...
- MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。
MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得. 之前的项目比较简单,多是用JSP .Servlet + JDBC 直接搞定,在项目中尝试用 Strut ...
随机推荐
- visual studio中使用vim快捷键
vsvim下载链接: https://marketplace.visualstudio.com/items?itemName=JaredParMSFT.VsVim 下载,关闭visual studio ...
- 对数组内容使用了json_encode返回汉字内容返回了空值
如果使用json_encode对数组进行转成JSON字符串时候,发现汉字的全部为空,这样可以说明的一点是你的页面上用的一定不是UTF8编码,在PHP手册中对json_encode中待编码的值已经说明所 ...
- linux批量检测服务器能否ping通和硬盘容量状态并抛出报警的一个脚本-附详细解释
有一些linux基础,最近刚开始学shell,参考了阿良老师的一个监测服务器硬盘状态的脚本,自己进行了一些扩展,今天比较晚了,后边会把注释放上来,感觉脚本还很不完善,希望大家一起探讨一下,共同学习 2 ...
- [AI开发]基于DeepStream的视频结构化解决方案
视频结构化的定义 利用深度学习技术实时分析视频中有价值的内容,并输出结构化数据.相比数据库中每条结构化数据记录,视频.图片.音频等属于非结构化数据,计算机程序不能直接识别非结构化数据,因此需要先将这些 ...
- Java 新手学习日记一
Java 基础知识点掌握: 数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间.内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此 ...
- 【02】一个实现h5的拖放的整个过程-魔芋
[02]拖放的整个过程-魔芋 01,创建2个元素,一个为拖放元素dragEle,一个是存放的元素targetEle.添加一些样式. <div class="dragEle&qu ...
- MySQL语句之or和and多条件查询
在where中可以包含任意数目的and和or操作符,需要注意的是在没有任何其他符号的时候,例如括号,AND的优先级高于OR,因此,当两者一起使用时,先运算AND两边的条件表达式,再运算OR两边的条件表 ...
- 【Ajax 2】封装Ajax的核心对象:XMLHttpRequest对象
导读:AJAX利用一个构建到所有现代浏览器内部的对象-XMLHttpRequest-来实现发送和接收HTTP请求与响应信息.那么,XMLHttpRequest对象是怎么创建和封装的呢? 一.简介 1. ...
- LibreOJ2302 - 「NOI2017」整数
Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...
- docker容器的导入导出
导出容器docker export 导出容器快照到本地文件$ sudo docker ps -aCONTAINER ID IMAGE COMMAND ...