MVC架构模式(2)
简介:
MVC最初是在Smaltalk_80中被用来构建用户界面的。M代表模型Model,V代表视图View,C代表控制器Controller。
Model模型层,可以简单理解就是数据层,用于提供数据。在项目中,(简单理解)一般把数据访问和操作,比如将对象关系映射这样的代码作为Model层,也就是对数据库的操作这一些列的代码作为Model层。比如代码中我们会写DAO类型的代码,这个DAO可以理解为是属于Model层的代码。
View视图层,就是UI界面,功能是与用户进行交互。一般所有的JSP、Html等页面就是View层。
Controller控制层,Controller层的功能就是将Model和View层进行关联。比如View主要是显示数据的,但是数据又需要Model去访问,这样的话,View会先告诉Controller,然后Controller再告诉Model,Model请求完数据之后,再告诉View。
MVC重要特点就是两种分离:
视图和数据模型的分离:使用不同的视图对相同的数据进行展示;分离可视和不可视的组件,能够对模型进行独立测试。因为分离了可视组件减少了外部依赖利于测试。(数据库也是一种外部组件)
视图和表现逻辑(Controller)的分离:Controller是一个表现逻辑的组件,并非一个业务逻辑组件。MVC可以作为表现模式也可以作为建构模式,意味这Controller也可以是业务逻辑。分离逻辑和具体展示,能够对逻辑进行独立测试。
优点:耦合性低;重用性高;生命周期成本低;部署块;可维护性高;有利软件工程化管理。
缺点:没有明确的定义;不适合小型,中等规模的应用程序;增加系统结构和实现的复用性;视图与控制器间的过于紧密的连接;视图对模型数据的低效率访问;一般高级的界面工具或构造器不支持模式。
适用场景:
MVC 可以说是最经典的架构模式,它适用于大部分的开发场景,如果对架构不怎么了解,在MVC架构基础上进行封装与优化可以满足绝大部分的需求
解决的问题:
实现一种动态的程序设计,是后序对程序的修改和扩展简化,并且使程序某一部分的重复利用称为可能。
通过对复杂度的简化,使程序结构更加直观。
将信息的内部表示与信息的呈现方式分离开来,并接受用户的请求。它分离了组件,并允许有效的代码重用。即,将模型和视图的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保模型和视图的同步,一旦模型改变,视图应该同步更新。
增加代码的重用率,减少数据表达、数据描述和应用操作的耦合度。同时也使得软件可维护性、可修复性、可扩展性,灵活性以及封装性大大提高
解决方案:
通过把职责、性质相近的成分归结在一起,不相近的进行隔离,MVC将系统分解为模型、视图、控制器三部分,每一部分都相对独立,职责单一,在实现过程中可以专注于自身的核心逻辑。MVC是对系统复杂性的一种合理的梳理与切分,它的思想实质就是“关注点分离”。
实例:
应用于基于MVC架构模式的框架,常见的服务器端MVC框架有:Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;常见前端MVC框架:angularjs、reactjs、backbone;由MVC演化出了另外一些模式如:MVP、MVVM。
其实 Android 开发本身默认的就是一套 MVC 实现。
View 层:Android 开发中的 xml 布局就是我们的 View 层,默认情况下也建议 View 都尽量用 xml 实现,当然对于一些复杂的就需要我们自定义 View 了,自定义 View 同样也是属于 View 层,只不过大多数时候还是 xml 布局用的最多。
Controller 层:毫无疑问,Android 默认也给我们提供了 Controller,就是 Activity & Fragment,仔细想想,是不是用户的交互事件,如输入、点击、滑动等都是在 Activity、Fragment 中处理的?关于这点有人认为 Activity & Fragment 属于 View 层,这个我是不认可的,View 应该专注界面的显示,Controller 处理用户的交互,提供给 View 需要的数据,从而让 View 正确的显示出来,而这都是 Activity & Fragment 的工作。
Model 层:Android 中对 View 与 Controller 有了定义,其实没有对 Model 层做定义,而大部分架构都不会对 Model 层做定义,因为 Model 本身是跟业务相关,针对不同的业务模型,定义需要的数据模型与实体类,以及相关的业务逻辑处理,虽然 Android 没有明确定义 Model 层,但是我们在开发中都会定义一个专门的 model package 用来统一管理所有的 model 文件,如 User、Order、Chat 等。
下面举几个简单的例子:
例如①,小时候玩的那种卡带式游戏机,Control是主机,一般来说我买一个主机就行了,只要他不坏,他就能一直让我玩这一类的游戏。View则是电视机和游戏手柄,电视机可以独立工作,他不管输入的是电视信号、影碟机信号还是游戏机信号,他只管显示,而且他决定了我们看到的效果是怎么样的,如果我想要个尺寸更大的或者彩色的显示效果,我只需要买个相应的电视机就行了,手柄也是可以换的,遥杆还是带震动的。Model则是游戏卡带,他决定了我玩的是什么游戏,是魂斗罗还是超级玛莉,而且游戏机主机和电视机生产厂家永远也不知道在上面有可能会运行什么样的游戏。卡带中可能会有游戏代码和存储单元,都根据游戏的需要而设计。
例如②,一个采用比例表示的用于政治选举的一个简单信息系统,它提供了一个输入数据的电子数据表和表示当前结果的几种图标。用户可以通过图形接口与系统交互。所有信息显示必须立即反应出选举数据的变化。(引用自《面向模式的软件体系结构-卷1 模式系统》)
即,一旦模型的数据发生了变化,模型要通报所有的视图。
MVC和三层架构的区别与联系:
很多人都很容易把MVC和三层架构模式混淆,但其实两者有很大的区别。
三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:
表现层(UI):展现给用户的界面
业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理
数据访问层(DAL)::该层所做事务直接操作数据库,针对数据的增添、删除、修改、更新、查找等
严格来说MVC(Model-View-Controller)三个加起来以后才是三层架构中的UI层,也就是说,MVC把三层架构中的UI层再度进行了分化,分成了控制器、视图、实体三个部分,控制器完成页面逻辑,通过实体来与界面层完成通话;而C层直接与三层中的BLL进行对话。
MVC是表现层的架构,MVC的Model实际上是ViewModel,即供View进行展示的数据。 ViewModel不包含业务逻辑,也不包含数据读取。 而在N层架构中,一般还会有一个Model层,用来与数据库的表相对应,也就是所谓ORM中的O。这个Model可能是POCO,也可能是包含一些验证逻辑的实体类,一般也不包含数据读取。进行数据读取的是数据访问层。而作为UI层的MVC一般不直接操作数据访问层,中间会有一个业务逻辑层封装业务逻辑、调用数据访问层。UI层(Controller)通过业务逻辑层来得到数据(Model),并进行封装(ViewModel),然后选择相应的View