设计模式
设计模式简介
看懂UML类图和时序图
UML统一建模语言
UML类图及类图之间的关系
类关系记忆技巧
如何正确使用设计模式
优秀设计的特征
面向对象设计原则
创建型设计模式
工厂模式
抽象工厂模式
简单工厂模式
静态工厂模式(Static Factory)
单例模式
建造者模式
原型模式
结构型设计模式
适配器模式
桥接模式
组合模式
装饰器模式
外观模式
享元模式
代理模式
过滤器模式
注册模式(Registry)
行为型设计模式
责任链模式
命令模式
解释器模式
中介者模式
备忘录模式
迭代器模式
观察者模式
状态模式
策略模式
模板模式
访问者模式
规格模式(Specification)
J2EE 设计模式
MVC 模式
业务代表模式
组合实体模式
数据访问对象模式(DAO模式)
前端控制器模式
拦截过滤器模式
空对象模式
服务定位器模式
传输对象模式
数据映射模式(Data Mapper)
依赖注入模式(Dependency Injection)
流接口模式(Fluent Interface)
其他模式
对象池模式(Pool)
委托模式
资源库模式(Repository)
实体属性值模式(EAV 模式)
反面模式
归纳设计模式
本文档使用 MrDoc 发布
-
+
首页
MVC 模式
> MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。 ![The Model View Controller Pattern – MVC Architecture and Frameworks Explained](/media/202203/2022-03-17_1922430.24931457143272895.png) ## 介绍 模型-视图-控制器 (MVC) 体系结构模式将应用程序分成 3 个主要组件组:模型、视图和控制器。 此模式有助于实现关注点分离。 使用此模式,用户请求被路由到控制器,后者负责使用模型来执行用户操作和/或检索查询结果。 控制器选择要显示给用户的视图,并为其提供所需的任何模型数据。 ![MVC](/media/202203/2022-03-17_1928510.5926651554806259.png) * **Model(模型)** : 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。编写程序应有的功能(实现算法等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。 * **View(视图)** : 视图代表模型包含的数据的可视化。界面设计人员进行图形界面设计。 * **Controller(控制器)** : 控制器作用于模型和视图上。它**控制数据流向模型对象**,**并在数据变化时更新视图**。它使视图与模型分离开。负责转发请求,对请求进行处理。 这种责任划分有助于**根据复杂性缩放应用程序**,因为这更易于编码、调试和测试包含单一作业的某个组成部分(模型、视图或控制器)。 但这会加大更新、测试和调试代码的难度,该代码在这 3 个领域的两个或多个领域间存在依赖关系。 例如,**用户界面逻辑的变更频率往往高于业务逻辑**。 如果将表示代码和业务逻辑组合在单个对象中,则每次更改用户界面时都必须修改包含业务逻辑的对象。 这常常会引发错误,并且需要在每次进行细微的用户界面更改后重新测试业务逻辑。 > **视图和控制器均依赖于模型**。 但是,**模型既不依赖于视图,也不依赖于控制器**。 这是分离的一个关键优势。 这种分离允许模型独立于可视化展示进行构建和测试。 ### 模型责任 MVC 应用程序的模型 (M) **表示应用程序和任何应由其执行的业务逻辑或操作的状态**。 业务逻辑应与保持应用程序状态的任何实现逻辑一起封装在模型中。 用于封装与应用程序业务逻辑相关的数据以及对数据的处理方法。**Model 有对数据直接访问的权力**,例如对数据库的访问。**Model 不依赖 View 和 Controller**,也就是说, **Model 不关心它会被如何显示或是如何被操作**。但是 **Model 中数据的变化一般会通过一种刷新机制被公布**。为了实现这种机制,那些用于监视此 Model 的 View 必须事先在此 Model 上注册,由此,View 可以了解在数据 Model 上发生的改变。(如,软件设计模式中的“观察者模式”)。 ### 视图责任 视图 (V) 负责通过用户界面展示内容。 视图中应该有最小逻辑,并且其中的任何逻辑都必须与展示内容相关。 能够**实现数据有目的的显示**(理论上,这不是必需的)。在 View 中**一般没有程序上的逻辑**。为了实现 View 上的刷新功能,**View 需要访问它监视的数据模型**(即 Model),因此应该事先在被它监视的数据那里注册。 ### 控制器职责 控制器 (C) 是处理用户交互、使用模型并最终选择要呈现的视图的组件。 在 MVC 应用程序中,视图仅显示信息;控制器处理并响应用户输入和交互。 在 MVC 模式中,**控制器是初始入口点**,负责选择要使用的模型类型和要呈现的视图(因此得名 - 它控制应用如何响应给定请求)。 起到不同层面间的组织作用,用于**控制应用程序的流程**。它处理事件并作出响应。**“事件”包括用户的行为和数据 Model 上的改变**。 > 控制器不应由于责任过多而变得过于复杂。 **要阻止控制器逻辑变得过于复杂,请将业务逻辑推出控制器并推入域模型**。 视图层与模型层是通过控制层联系起来的,两者之间并无直接的联系: ![视图层与模型层是通过控制层联系起来](/media/202203/2022-03-18_1012420.2138797756173484.png) 如果单纯从数据流的角度来看,模型层、控制层和视图层分别代表着**数据的来源于处理、数据的分发和数据的展示** 3 个部分,如果从用户交互角度来看,则又分别代表着**交互行为的产生、交互行为的控制分发和交互行为的数据支持**。 ## 优点 ### 低耦合 通过将视图层和业务层分离,允许更改视图层代码而不必重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变,只需要改动 MVC 的模型层(及控制器)即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。 模型层是自包含的,并且与控制器和视图层相分离,所以很容易改变应用程序的数据层和业务规则。如果想把数据库从 MySQL 移植到 Oracle,或者改变基于 RDBMS 的数据源到 LDAP,只需改变模型层即可。一旦正确的实现了模型层,不管数据来自数据库或是 LDAP 服务器,视图层都将会正确的显示它们。由于运用 MVC 的应用程序的三个部件是相互独立,改变其中一个部件并不会影响其它两个,所以依据这种设计思想能构造出良好的松耦合的构件。 ### 重用性高 随着技术的不断进步,当前需要使用越来越多的方式来访问应用程序了。MVC 模式允许使用各种不同样式的视图来访问同一个服务端的代码,这得益于多个视图(如 WEB(HTTP)浏览器或者无线浏览器(WAP))能**共享一个模型**。 比如,用户可以通过电脑或通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式(流程)是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面(视图)使用。例如,很多数据可能用 HTML 来表示,但是也有可能用 WAP 来表示,而这些表示的变化所需要的是仅仅是改变视图层的实现方式,而控制层和模型层无需做任何改变。 由于已经将数据和业务规则从表示层分开,所以可以最大化的进行代码重用了。另外,模型层也有状态管理和数据持久性处理的功能,所以,基于会话的购物车和电子商务过程,也能被 Flash 网站或者无线联网的应用程序所重用。 ### 生命周期成本低 MVC 模式使开发和维护用户接口的技术含量降低。 ### 部署快 使用 MVC 模式进行软件开发,使得软件开发时间得到相当大的缩减,它**使后台程序员集中精力于业务逻辑,界面(前端)程序员集中精力于表现形式上**。 ### 可维护性高 分离视图层和业务逻辑层使得 WEB 应用更易于维护和修改。 ### 有利软件工程化管理 由于不同的组件(层)各司其职,每一层不同的应用会具有某些相同的特征,这样就有利于通过**工程化、工具化的方式管理程序代码**。控制器同时还提供了一个好处,就是可以使用控制器来联接不同的模型和视图,来实现用户的需求,这样控制器可以为构造应用程序提供强有力的手段。**给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型进行处理,然后选择视图将处理结果显示给用户**。 ### 视图对模型数据的低效率访问 **依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能**。说明:如果通过控制器访问模型层(而非视图层直接访问),或许可避免对未变化数据的不必要的频繁访问,从而解决此问题。 ## 缺点 ### 没有明确的定义 完全理解 MVC 模式并不是很容易的。使用 MVC 模式需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考软件的架构。同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。 ### 不适合小、中型应用程序 花费大量时间将 MVC 模式应用到规模并不是很大的应用程序通常会得不偿失。(但是这种情况可以通过 MVC 框架来解决) ### 增加系统结构和实现的复杂性 对于简单的界面来说,非要严格遵循 MVC 模式,使模型、视图与控制器分离的话,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。 ## 应用 ![MVC 结构](/media/202203/2022-03-18_1042550.7185636483629148.png) MVC 模式在概念上强调 Model, View, Controller 的分离,各个模块也遵循着由 Controller 来处理消息,Model 掌管数据源,View 负责资料显示的职责分离原则,因此在实现上,MVC 模式的 Framework 通常会将 MVC 三个部分分离实现: * Model 负责资料访问,较现代的 Framework 都会建议使用独立的资料对象 (DTO, POCO, POJO 等) 来替代弱类型的集合对象。资料访问的代码会使用 Data Access 的代码或是 **ORM-based Framework**,也可以进一步使用 **Repository Pattern** 与 **Unit of Works Pattern** 来切割数据源的相依性。 * Controller 负责处理消息,较高端的 Framework 会有一个默认的实现来作为 Controller 的基础,例如 Spring 的 DispatcherServlet 或是 ASP.NET MVC 的 Controller 等,在职责分离原则的基础上,每个 Controller 负责的部分不同,因此会将各个 Controller 切割成不同的文件以利维护。 * View 负责显示资料,这个部分多为前端应用,而 Controller 会有一个机制将处理的结果 (可能是 Model, 集合或是状态等) 交给 View,然后由 View 来决定怎么显示。例如 Spring Framework 使用 JSP 或相应技术,ASP.NET MVC 则使用 Razor 处理资料的显示。 > MVC 不是一种技术,而是一种理念。 ## 代码示例 ### js ```js /** 模拟 Model, View, Controller */ var M = {}, V = {}, C = {}; /** Model 负责存放资料 */ M.data = "hello world"; /** View 负责将资料输出给用户 */ V.render = (M) => { alert(M.data); } /** Controller 作为连接 M 和 V 的桥梁 */ C.handleOnload = () => { V.render(M); } /** 在网页读取的时候呼叫 Controller */ window.onload = C.handleOnload; ``` ## MVC 框架 ### Java J2EE:和其他的各种框架不一样,J2EE为模型对象(Model Objects)定义了一个规范。 - 视图(View):在J2EE应用程序中,视图(View)可能由**Java Server Page(JSP)**担任。生成 View 的代码则可能是一个servlet的一部分,特别是在客户端服务端交互的时候。 - 控制器(Controller):J2EE应用中,Controller 可能是一个**servlet**。除了可直接以J2EE来撰写外,亦可用其他框架来撰写,常见的有Struts2、Spring Framework等等。 - 模型(Model):Model 则是由一个实体Bean来实现。 ### Python Python 有许多的 MVC 架构。最常用的有 Django 和 TurboGears。 ### JavaScript * [Backbone.js](https://zh.wikipedia.org/wiki/Backbone.js "Backbone.js") * [Angular.js](https://zh.wikipedia.org/wiki/AngularJS "AngularJS") * [Ember.js](http://emberjs.com/) * [JavaScriptMVC](https://zh.wikipedia.org/wiki/JavaScriptMVC "JavaScriptMVC") * [Model-View-Controller (MVC) with JavaScript](https://web.archive.org/web/20070927183315/http://www.alexatnet.com/node/8)
追风者
2022年3月18日 10:43
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码