MVC, MVP, MVVM总结——MVC篇
2012-08-22 09:00 JustRun 阅读(1688) 评论(0) 编辑 收藏 举报1. 这些模式诞生的源需求
程序的最原始的内容就是数据.
围绕着数据的产生、修改等变化,出现了业务逻辑, 围绕着数据的显示,出现了不同的界面技术.
没有设计的代码,会出现数据层(持久层)和业务逻辑层还有界面代码耦合的情况。
ORM解决业务逻辑和数据之间的耦合。
MVC, MVP, MMVM用来解决业务逻辑和视图之间的耦合
2. 经典的MVC模式
Model:
用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。Model有对数据直接访问的权力,例如对数据库的访问。
模型中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变。
View:
视图层能够实现数据有目的的显示(理论上,这不是必需的)。
在视图中一般没有程序上的逻辑。为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。
Controller:
控制器起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据模型上的改变。
3. 真实在Web中使用的MVC
上面是Structs中的MVC的一个请求的流程, asp.net中的MVC应该类似。
Web应用中的MVC架构与通常所说的MVC架构有一点区别。
主要区别在于:
在通常所说的MVC架构中,当model发生变化时,会主动更新对应的view视图,view与model是同步的.
而在web应用中,由于http是基于请求和响应方式协同工作的,因此当服务器端的model(数据)发生变化时,它不会立即更新客户端的view,只有客户端重新请求或刷新页面时才更新.
4. MVC的优点
- 降低了系统的耦合性
- 开发速度快,程序员和界面设计人员可以相对对立工作。
- 可维护性高
- 没有控件的概念,对html没有封装,易于理解
- Asp.Net MVC和其它平台(java, php)等更加相似。便于人才获取
5. MVC使用的误区
- 把Model当做实体类(Entity),作为View和Controller之间的传输数据。
- 把业务逻辑全部放在Controller端,认为Controller是用来写UI的业务逻辑的。
这两个误区本质上都是对Model的作用不明导致的。
Model在MVC架构中起的作用非常重要,它才是UI业务逻辑真正的实现层。所以Model的实际上是Business Model(业务模型)。而Controller仅仅起一个“桥梁”作用,它负责把View的请求转发给Model,再负责把Model处理结束的消息通知View。Controller就是一个消息分发器。Controller是用来解耦View和Model的,具体一点说,就是为了让UI与逻辑分离(界面与代码分离)。
6. WinForm中的MVC
实现WinForm中的MVC是比Web复杂的事情,Controller要能够在Model和View之间自如游走的一个前提是对所有的事件进行拦截.
Web中的请求拦截非常容易,因为只有一个入口,而且很容易区分不同请求, 通过URL mapping来转向不同Model
PureMVC实现Winform MVC的, 它通过:
1. 每个界面视图(winform窗体或User Control)都对事件进行有意义的封装, 隔绝了View和逻辑
比如, Save按钮是添加一条新的User记录, 那么会在Save按钮的click事件中,调用一个Event。 而这个Event是由其它的逻辑代码实现的,不在这个视图中实现。
#region AddUser public event EventHandler AddUser; //event AddUser, 有意义的一个对外接口,交由外部实现,分离显示和逻辑 public virtual void OnAddUser(EventArgs args) { if (AddUser != null) AddUser(this, args); } #endregion private void btnAddUser_Click(object sender, EventArgs e)//按钮事件, 无意义 { _user = new User{Name=textBox1.Text, Age = Convert.ToInt32(textBox2.Text)}; OnAddUser(e); }
2. 每个视图对外提供传递显示数据的接口
如这里提供一个公开方法,显示一个IList<User>到界面上
public void LoadUsers(IList<User> users) { this.dataGridView1.DataSource = null; this.dataGridView1.DataSource = users; }
3. 程序会为每个视图准备一个代理类(Mediator)
这个代理类会和对应的视图绑定,实现视图的public event, 调用Model, 也就是实际的逻辑代码
public UserAddMediator(UserAdd userAdd) :base(NAME, userAdd) { userAdd.AddUser += new EventHandler(userList_NewUser); } void userList_NewUser(object sender, EventArgs e) { var user = UserAdd.User; _userProxy.AddItem(user);//这里的_userProxy实际是Model层 SendNotification(ApplicationFacade.USER_ADDED, user);//在系统中发送Notification, 感兴趣的人会截获并处理这个Notification, 下面有讲到。 UserAdd.ClearForm(); }
调用视图的显示数据接口, 控制视图的呈现。
监听感兴趣的Notification和处理这些Notification
public override IList<string> ListNotificationInterests() { IList<string> list = new List<string>(); list.Add(ApplicationFacade.USER_ADDED); return list; } public override void HandleNotification(INotification note) { switch (note.Name) { case ApplicationFacade.USER_ADDED: UserList.LoadUsers(_userProxy.Users); break; } }
4. 整个最外层架构使用Facade模式, 解耦M和V, 通过Notification来串联整个系统。
PureMVC中没有关于WinForm的Demo代码,这里有一个简单的WinForm Demo.
本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名justrun(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。