面对对象的C语言:MVC简述

in 小得 with 0 comment

架构漫谈

提到架构,我们来看下维基百科的定义“软件架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。”嗯,好像说了什么,但仔细分辨起来是句正确的废话。那么,要想设计一个好的架构,我们首先要明确为什么要做一个架构设计,如果不做架构设计会怎么样。

首先,人类的思维是有局限性的,根据科学研究,人类最多能够关注7+2或7-2个点,这就是著名的72法则。超出这个范围,人类的思维就跟不上了。如果不做架构设计,系统就处于一种复杂的混沌状态,有几十上百甚至上千个技术点。当我们构思系统要实现某个功能或者业务时,需要同时关注几十上百个技术点,这是人的思维做不到的。所以我们必须将系统划分为几个大的模块,每次关注的点7+2或7-2个,这样人类的思维才能更好的思考、分析、解决问题。

其次,现代软件项目开发已经不可能由一个人全程负责,至少也是几个人的小团队合作,甚至于几个团队的合作。如果不做架构设计,系统就是一个大一统的的整体,这些团队成员无法分工合作。要么一拥而上,要么无从下手,整个系统的实现过程就会变成一团乱麻。所以,将系统划分为几个大的模块,不同的团队或成员负责不同的模块,从而达到分工工作的目的,提升整体工作效率。

所以,架构的目的主要有两点:一、隔离关注点,降低复杂度。二、更好的分工合作。

同时,应该看到,架构设计将系统划分为不同的模块的同时,并不能简单地一拆了事。还要考虑模块之间的关系,模块与模块的有机结合、互相联系、互相沟通、互相配合,这样才能够完成系统的功能。换言之:架构=模块+交互

MVC思想简述

同样的,我们先来看下维基百科对MVC架构的定义:“MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。”所有现代编程语言,凡是有GUI的,都有一套自己MVC的架构。为什么会这样呢?一方面同样是因为现代软件工程的专业度越来越高,分工越来越细,就像工业制造一样成为流水线作业。每个程序员术业有专攻,才能高效率的进行程序开发。另一方面同样是由于软件复杂度的提高,只有好的架构才能保障项目的可理解性、可维护性与可扩展性。

那么,我们来看看MVC具体定义:

模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
视图(View) - 界面设计人员进行图形界面设计。
控制器(Controller)- 负责转发请求,对请求进行处理,用于控制应用程序的流程。

他们之间的关系可以简单理解为:Model用来实现功能,View用来负责展示,他们之间通过Controller进行联系。

使用了MVC架构的好处是显而易见的。

首先,多个View可以共享同一个Model。不同的POS型号有着不同的分辨率、屏幕布局。在MVC设计模式中,具体业务逻辑和表示层分离,业务程序写的一个Model可以被不同的POS型号的View重用,只需要界面程序员对具体POS进行适配,大大提高了代码的可重用性。

其次,MVC模式的三个模块相互独立,改变其中一个不会影响其他两个。也就是说,View和Model可以独立进行测试与开发,便于程序员工作的合作开展。

MVC架构漫谈

还记得 架构=模块+交互,这个公式吧。将程序分为Model、View、Controller三个模块,这是所有MVC框架都明确的事情,即使有区别,也只是称呼上的区别。但对这三者的关系,却是各MVC架构很大的区别。这不只是技术实现上的区别,而是理念与认识上的区别。View是否依赖于Model,Model是否依赖于Controller。Controller应该靠近View还是靠近Model,或者是完全独立。这在工业界有着极大的争议,发展出不同的实现方法,如MVP(Model-View-Presenter)、MVVM(Model–view–viewmodel)。

其实,MVC并没有一个明确的定义,网上流传的MVC架构图也是形态各异,查阅了很多资料也没有办法确定到底什么样的架构图才是标准的MVC实现。ASP.NET MVC、Spring MVC、iOS MVC、Rails MVC各说各话,都不一样。这里以Martin Fowler在GUI Architectures论文中的描述为例。
Essential-Dependencies-in-MVC.jpg

模型层可以单独工作,而视图层和控制器层都依赖与模型层中的数据。

以下都要改,先摘抄如下:

分离展示层

在 Martin Fowler 对于 Model-View-Controller 的描述中,MVC 最重要的概念就是分离展示层 Separated Presentation,如何在领域对象(Domain Object)和我们在屏幕上看到的 GUI 元素进行划分是 MVC 架构模式中最核心的问题。

GUI 应用程序由于其需要展示内容的特点,分为两个部分:一部分是用于展示内容的展示层(Presentation Layer),另一部分包含领域和数据逻辑的领域层(Domain Layer)。

展示层依赖于领域层中存储的数据,而领域层对于展示层一无所知,领域层其实也是 MVC 模式中的模型层,而展示层可以理解为 VC 部分。

MVC 最重要的目的并不是规定各个模块应该如何交互和联系,而是将原有的混乱的应用程序划分出合理的层级,把一团混乱的代码,按照展示层和领域层分成两个部分;在这时,领域层中的领域对象由于其自身特点不需要对展示层有任何了解,可以同时为不同的展示层工作。

观察者同步

除了分离展示层,MVC 还与观察者同步 Observer Synchronization 关系紧密。因为在 MVC 模式中,模型可以单独工作,同时它对使用模型中数据的视图和控制器一无所知,为了保持模型的独立性,我们需要一种机制,当模型发生改变时,能够同时更新多个视图和控制器的内容;在这时,就需要以观察者同步的方式解决这个问题。

我们将所有需要实时更新的组件注册成为模型的观察者,在模型的属性发生变化时,通过观察者模式推送给所有注册的观察者(视图和控制器)。

当多个视图共享相同的数据时,观察者同步是一个非常关键的模式,它能够在对这些视图不知情的前提下,同时通知多个视图;通过观察者模式,我们可以非常容易地创建一个依赖于同一模型的视图。

观察者同步或者说观察者模式的主要缺点就是:由于事件触发的隐式行为可能导致很难查找问题的来源并影响其解决,不过虽然它有着这样的缺点,但是观察者同步这一机制仍然成为 MVC 以及其衍生架构模式中非常重要的一部分。

占主导地位的控制器

MVC 架构模式的三个组成部分:Model、View 和 Controller 中最重要的就是控制器,它承担了整个架构中的大部分业务逻辑,同时在用户请求到达或者事件发生时都会首先通知控制器并由它来决定如何响应这次请求或者事件。

在 MVC 中,所有的用户请求都会首先交给控制器,再由控制器来决定如何响应用户的输入,无论是更新模型中的信息还是渲染相应的视图,都是通过控制器来决定的;也就是说,在 MVC 中,控制器占据主导地位,它决定用户的输入是如何被处理的。

被动的模型

在绝大多数的 MVC 架构模式中,模型都不会主动向视图或者控制器推送消息;模型都是被动的,它只存储整个应用中的数据,而信息的获取和更新都是由控制器来驱动的。

但是当模型中的数据发生变化时,却需要通过一些方式通知对应的视图进行更新,在这种情况下其实也不需要模型主动将数据变化的消息推送给视图;因为所有对于模型层的改变都是由用户的操作导致的,而用户的操作都是通过控制器来处理的,所以只需要在控制器改变模型时,将更新的信息发送给视图就可以了;当然,我们也可以通过观察者模式向未知的观察者发送通知,以保证状态在不同模块之间能够保持同步。

作为被动的模型层,它对于视图和控制器的存在并不知情,只是向外部提供接口并响应视图和控制器对于数据的请求和更新操作。

1 https://zh.wikipedia.org/wiki/MVC#cite_ref-1
[2] https://my.oschina.net/jimilee/blog/727841
[3] https://my.oschina.net/jimilee/blog/732017
[4] https://martinfowler.com/eaaDev/uiArchs.html
[5]

Responses