zoukankan      html  css  js  c++  java
  • MVC, MVP, MVVM总结——MVC篇

    1. 这些模式诞生的源需求

    程序的最原始的内容就是数据.

    围绕着数据的产生、修改等变化,出现了业务逻辑, 围绕着数据的显示,出现了不同的界面技术.

    没有设计的代码,会出现数据层(持久层)和业务逻辑层还有界面代码耦合的情况。

    ORM解决业务逻辑和数据之间的耦合。

    MVC, MVP, MMVM用来解决业务逻辑和视图之间的耦合

    2. 经典的MVC模式

    Model:

    用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。Model有对数据直接访问的权力,例如对数据库的访问。

    模型中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变。

    View:

    视图层能够实现数据有目的的显示(理论上,这不是必需的)。

    在视图中一般没有程序上的逻辑。为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。

    Controller:

    控制器起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据模型上的改变。

    image

    3. 真实在Web中使用的MVC

    image

    上面是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使用的误区

    1. 把Model当做实体类(Entity),作为View和Controller之间的传输数据。
    2. 把业务逻辑全部放在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.

    WinformMVC.zip

  • 相关阅读:
    [linux] ubuntu gnome 控制面板恢复
    [linux] grub修改
    [erlang] 合并list
    hdu4169 Wealthy Family (树形背包)
    hdu 3899 JLUCPC
    最大流模板
    hdu 4167 User Names
    hdu 2196 Computer (树形DP)
    hdu 1011 Starship Troopers(树形DP)
    hdu 2874 Connections between cities (LCA转RMQ)
  • 原文地址:https://www.cnblogs.com/JustRun1983/p/2650177.html
Copyright © 2011-2022 走看看