zoukankan      html  css  js  c++  java
  • GUI架构演进之MVC(一)

    背景

    说到GUI架构,我们一般会想到MVC,MVP,MVVM等;但是关于它们之间的关键区别,网络上的很多解释让人迷惑,看完之后令人更难区分它们了。

    如果你也是在看完各种解释之后仍然无法正确区分它们,甚至觉得MVP和MVVM只不过是一个新名词而与MVC无异时,你应该阅读我的这篇文章。

    实际上,造成这种困惑的关键原因在于MVC;经过漫长的时间,MVC的原始定义被修改了,甚至被曲解了;而MVP和MVVM是相对于原始MVC来定义的。

    例如,有些人就没有正确区分M(Model)和C(Controller),仅将M理解成数据类,而将对数据的操作理解为C,后面可以看到,这是极其错误的;

    例如,Cocoa文档所描述的MVC实际上是MVVM,具体可以看微软大牛写的文章Confusion over definition of Controller in MVCWhats a controller anyway?

    基本定义

    问题的关键是追根溯源,探究MVC的原始定义,搞清楚M,V和C的精确定义;SmallTalk的早期文档How to use Model-View-Controller (MVC)对此有描述。

    一般来说,GUI程序可以划分为问题建模,视觉显示或反馈和用户输入这三部分,而这也分别对应着M(Model),V(View)和C(Controller)。

    Model:应用程序问题域的建模,同时包括数据和行为部分,响应数据获取和更新请求;

    View:负责应用程序的界面展示,一般会从Model请求数据;

    Controller:负责接收并解释用户输入(例如鼠标,触摸,键盘),驱动Model和View做出反应,一般会请求Model更新数据,请求View刷新;

    从这里可以看出,Controller是界面展示的一部分而非是问题建模的一部分,这一点是需要重点注意的。

    MVC通信三角

    在程序中,Model,View和Controller之间必然要相互通信,具体的通信模式视情况而定,这里只说明最初始的模式。

    View和Controller本来就是协同设计的,它们互相持有对方的实例,相互之间按需进行通信(接口调用);

    View和Controller都持有Model的实例,并根据需要从Model获取数据或者请求Model更新数据;

    Model不能直接持有View和Controller的实例,它主要以两种方式参与到通信过程中来:

    作为被动Model(Passive Model),不主动参与通信过程,而是由View和Controller来主动执行查询或者更新,View的刷新时机由Controller控制,适用于较简单的情况;

    作为主动Model(Active Model),采用观察者模式,Model主动将变化通知给View或者Controller,View的刷新时机由Model控制,适用于比较通用的情况,即主流情况;

    MVC组成MVC三角,通常一个程序中存在很多MVC三角,它们之间相互关联和协作,共同完成程序提供的功能。

    SmallTalk的MVC实现

    上面关于MVC的描述来自于早期SmallTalk的GUI设计,因此了解下SmallTalk的MVC实现是有意义的。

    SmallTalk中内置了对MVC编程范式的支持,存在View,Controller以及Model类,分别对应着这几种角色,对编程起到规范化作用。

    在SmallTalk中,View和Controller一般是形式化的,存在丰富的类继承层次供应用程序直接使用,或者继承修改再使用;Model则属于应用程序问题域,一般不能形式化,由应用程序自由发挥,但是SmallTalk为Model与View和Controller之间的通信提供了机制和规范:

    Model发送changed消息给它的观察者View,触发View的update方法被调用,View通过一种反射的方式(aspect)调用Model来获取数据,然后刷新自己;这种反射的技术避免了View与Model的强依赖,否则将导致过多的类继承来处理从各种Model中获取数据的逻辑;这种技术也可以理解为是一种Adapter,一种ValueConverter,甚至是DataBinding。

    大体过程如下:

    1.View组织成树形结构,View只负责展示,不负责与用户交互;

    2.每个View对应一个Controller,Controller负责处理用户交互;

    3.Controller也组织成树形结构,与View的树形结构相对应;

    4.存在顶层或全局Controller,负责总体协调和提供系统行为;

    5.整个GUI由顶层Controller启动control loop进入事件循环,接收用户交互;

    6.当用户与程序交互时,焦点View对应的Controller被选择来处理用户交互;

    7.Controller在处理用户交互时,除了可能会更新Model,也会直接或间接刷新View;

    可以看出,SmallTalk的GUI与Android的GUI大体相同,区别在于SmallTalk严格区分了View和Controller,而Android没有进行这种区分;SmallTalk的这种严格区分View和Controller的做法,对我们今天来理解MVC造成了比较大的困惑;事实上,随着MVC的演进,这种严格区分View和Controller的做法被逐渐淡化了,将View和Controller合二为一为Widget则成为主流(例如Android),但应用程序仍需要保留一个顶层Controller来负责组装串联各部分的逻辑(例如Android的Activity);但是这种Widget的形式淡化了Controller,对编程缺乏引导和规范,导致很多时候写出的代码并非遵循MVC模式,而是Forms and Controls模式,这个后面再写文章单独说明。

  • 相关阅读:
    萌新向Python数据分析及数据挖掘 第三章 机器学习常用算法 第三节 梯度下降法 (上)理解篇
    萌新向Python数据分析及数据挖掘 第三章 机器学习常用算法 第二节 线性回归算法 (下)实操篇
    萌新向Python数据分析及数据挖掘 第三章 机器学习常用算法 第二节 线性回归算法 (上)理解篇
    萌新向Python数据分析及数据挖掘 第三章 机器学习常用算法 第一节 KNN算法 (下)实操篇
    萌新向Python数据分析及数据挖掘 第三章 机器学习常用算法 第一节 KNN算法 (上)理解篇
    萌新向Python数据分析及数据挖掘 第二章 pandas 第五节 Getting Started with pandas
    Oracle数据库安装和授权
    c# 如何获取JSON文件以及如何获取Config文件(framework 和 net .Core)
    C#Core查询数据库存储EXCEL文件
    如何在WINDOW系统下编译P12证书制作
  • 原文地址:https://www.cnblogs.com/frydsh/p/14564420.html
Copyright © 2011-2022 走看看