同义词mvc(mvc)一般指MVC框架
- 中文名
- MVC框架
- 外文名
- MVC
- 所属学科
- 软件工程
- 全 名
- Model View Controller
- 架构内容
- 视图,模型,控制器
- 类 别
- 软件构件模式
历史背景
播报编辑
MVC 是图形用户界面早期开发中的一个开创性洞见,是描述和实现软件结构的首批方法之一 。Trygve Reenskaug 在 20 世纪 70 年代末在施乐帕洛阿尔托研究中心(Xerox PARC)作为访问科学家工作时创建了 MVC,当时他正在 Smalltalk-79 上工作 [4]。他想要一种模式,可以用来构建任何用户与大型、复杂的数据集交互的程序。他的最初设计包括四个部分:模型、视图、事物和编辑器。在与其他Smalltalk开发人员讨论后,他和团队最终确定了模型、视图和控制器。在他们的最终设计中,模型代表程序的某个部分,以纯粹和直观的方式。
视图是模型的视觉表示,从模型检索数据以显示给用户,并将用户和模型之间的请求来回传递。控制器是用户界面的组织部分,它在屏幕上布置和协调多个视图,并接收用户输入,并向其下层视图发送适当的消息。这个设计还包括一个编辑器,作为用于修改特定视图的控制器的特化形式,并通过该视图创建。Smalltalk-80 支持从这个设计演变而来的 MVC 版本。它提供了抽象的视图和控制器类,以及代表不同通用小部件的各个具体子类。在这个方案中,视图代表以某种方式向用户显示信息,控制器代表用户与视图交互的方式。视图还与模型对象关联,但该对象的结构完全由应用程序程序员决定。Smalltalk-80 环境还包括一个“MVC 检查器”,这是一个开发工具,用于并排查看给定模型、视图和控制器的结构 [6] 。
1988 年,两位前 PARC 员工在《面向对象技术杂志》(JOT)上的一篇文章中,将 MVC 作为 Smalltalk-80 开发人员的一般“编程范式和方法论”进行了介绍。然而,他们的方案与 Reenskaug 等人的方案和小 talk-80 参考书籍中介绍的方案都有所不同。他们将视图定义为涵盖任何图形关注点,控制器则是一个更抽象、通常不可见的对象,它接收用户输入并与一个或多个视图和一个模型交互。
MVC 模式随后发展,产生了诸如层次化模型-视图-控制器(Hierarchical-Model-View-Controller,HMVC)、模型-视图-适配器(Model-View-Adapter,MVA)、模型-视图-展示者(Model-View-Presenter,MVP)、模型-视图-视图模型(Model-View-View-Model,MVVM)等变体,这些变体将 MVC 适应于不同的上下文。随着 1996 年 NeXT的 WebObjects 的推出,MVC 模式在 Web 应用程序中的使用得到了增长,该框架最初是用 Objective-C 编写的(这种语言在很大程度上借鉴了 Smalltalk),并帮助强化了 MVC 原则。后来,当 WebObjects 被移植到 Java 时,MVC 模式在 Java 开发人员中变得流行。随后的 Java 框架,如 Spring(2002 年 10 月发布),继续强化了 Java 和 MVC 之间的紧密联系。
2003 年,Martin Fowler 出版的《企业应用架构模式》一书,将MVC 描述为一种模式,其中“输入控制器”接收请求,向模型对象发送适当的消息,从模型对象获取响应,并将响应传递给适当的视图进行显示 [5] 。这与 Ruby on Rails Web 应用程序框架(2004 年 8 月)的方法非常接近,该框架通过浏览器视图将客户端请求发送给服务器,这些请求由服务器上的控制器处理,控制器与适当的模型对象通信。Django 框架(2005 年 7 月,适用于 Python)提出了类似的“模型模板视图”(Model-Template-View,MTV)模式,其中视图从模型检索数据并将其传递给模板进行显示。Rails 和Django 都强调快速部署,这增加了 MVC 在传统企业环境之外的流行度 [2] 。
主要组件
播报编辑
MVC 分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。以下是对 MVC 框架的主要组件的简要介绍,其框架图在概述图中所示。
模型
模型是MVC框架的核心组成部分,它承担着管理应用程序数据和业务逻辑的重要责任。在模型中,数据被有效地管理、存储和操作,包括从各种数据源获取数据、对数据进行验证和处理、执行业务规则等。模型通常包括数据访问对象(Data Access Objects,DAO),用于与数据存储交互,以及实体类来表示应用程序中的核心数据结构。除此之外,模型也负责数据的通知和变化,确保数据变化时其他组件(如视图和控制器)能够及时获取到更新的数据。通过模型的设计,应用程序可以实现清晰的数据管理和业务逻辑,同时保持良好的可维护性、可扩展性和可测试性。同时模型会对数据进行校验和验证,确保数据的完整性、有效性和一致性。这可以通过验证规则、数据约束和业务规则来实现,以防止无效或不良数据进入系统。
模型的设计和实现对应用程序的整体质量和性能至关重要。一个良好设计的模型能够提供清晰的数据管理和业务逻辑,同时保持可维护性、可扩展性和可测试性,从而为应用程序的开发和维护提供了基础。
视图
视图是 MVC 框架中的另一个关键组件,它负责将模型的数据以用户友好的方式呈现给用户,并接收用户的输入。在视图中,用户界面元素被设计和排列,以展示应用程序的信息和功能。视图通常包括各种用户界面组件,如文本框、按钮、下拉菜单等,以及对数据的展示和呈现逻辑。与模型相对应的是视图不包含业务逻辑,它专注于数据的展示和用户交互。视图通常与具体的用户界面技术(如 HTML、JSP、Thymeleaf 等)紧密相关,通过视图解析器来将逻辑视图名称映射到实际的视图实现。通过良好设计的视图,用户可以直观地与应用程序交互,并获取所需的信息和功能,从而提升了用户体验和应用程序的易用性。
例如在 Smalltalk-80 中,视图只是模型的视觉表示,不处理用户输入。在使用 WebObjects 时,视图代表完整的用户界面元素,如菜单或按钮,并且确实接收用户输入。然而,在 Smalltalk-80 和 WebObjects中,视图旨在通用且可组合。在使用 Rails 和 Django 时,视图的角色由 HTML 模板扮演,因此在它们的方案中,视图指定了浏览器内用户界面,而不是直接代表用户界面小部件。(Django 选择将这种对象称为“模板”。)这种方法相对较少强调小型、可组合的视图;典型的 Rails 视图与控制器操作具有一对一的关系。
控制器
在 MVC 框架中,控制器不仅仅是接收请求和调用相应的处理方法,它还承担着更多的责任和功能 [13]。控制器负责从用户端接收各种类型的请求,包括 HTTP 请求、AJAX 请求等,然后根据请求的特征和内容进行路由和处理。它可能会根据请求的类型选择不同的处理逻辑,以满足不同类型请求的处理需求。
除了处理请求之外,控制器还负责协调模型和视图之间的交互。它将模型层返回的数据传递给视图层,以便视图能够呈现给用户。控制器可能会在处理过程中进行一些数据处理、格式化或转换,以确保数据能够被正确地显示在视图中。此外,控制器还可能涉及到一些与业务逻辑相关的操作,如数据验证、权限控制、日志记录等,以确保应用程序的安全性和稳定性。控制器的设计应该遵循单一职责原则,即每个控制器应该只负责处理特定类型或特定功能范围内的请求。这有助于提高代码的可维护性和可测试性,使得控制器可以更容易地被重用和扩展。通过良好设计的控制器,可以实现 MVC 框架的分离关注点原则,实现模型、视图和控制器之间的松耦合,从而为应用程序的开发和维护提供了基础。
在 Smalltalk-80 中,控制器处理用户输入事件,如按钮按下或鼠标移动。在任何给定时间,每个控制器都有一个相关的视图和模型,尽管一个模型对象可能会与多个不同的控制器交互。在 Rails 中,来自客户端的请求被发送到“路由器”,该路由器将请求映射到特定控制器的特定方法。在该方法中,控制器与请求数据和任何相关的模型对象交互,并使用视图准备响应。Django 将扮演此角色的对象称为“视图”,而不是控制器。Django 视图是一个函数,它接收 Web 请求并返回 Web 响应。它可能会使用模板来创建响应。
交互模式
播报编辑
除了将应用程序划分为这些组件外,模型-视图-控制器设计还定义了它们之间的交互。模型负责管理应用程序的数据,它从控制器接收用户输入,视图以特定格式呈现模型。控制器响应用户输入,并在数据模型对象上执行交互。控制器接收输入,可选择性地验证输入,然后将输入传递给模型。与其他软件模式一样,MVC 框架表达了问题的核心解决方案,同时允许其适应每个系统。特定的MVC 设计可能与这里提供的传统描述有显著差异。
设计动机
播报编辑
正如 Alan Kay 在 2003 年所写,MVC 背后的原始动机是为了允许为任何对象创建图形界面。Richard Pawson 在《Naked Objects》中提到 Naked Objects 框架(一种 MVC 框架)专门设计用于鼓励从行为完整的业务对象创建业务系统 [11] 。Trygve Reenskaug 在 PARC 创建 MVC 时写道,“MVC 是为了解决用户控制大型复杂数据集的问题而构思的一般解决方案。”在他们的 1991 年指南《Inside Smalltalk》中,CarletonUniversity 的计算机科学教授 Wilf LaLonde 和 John Pugh 描述了 Smalltalk-80 风格的 MVC 的优势为:
- 表示和数据的独立性,例如同时在同一个模型上拥有多个视图。
- 可组合的表示小部件,例如一个视图用作另一个视图的子视图。
- 可切换的输入模式,通过在运行时交换控制器来实现。
- 输入和输出处理的独立性,通过控制器和视图的独立职责实现。
应用框架
播报编辑
尽管 MVC 最初是为桌面计算开发的,但它已被广泛采用为 Web 应用程序的设计,在主要编程语言中。已经创建了几个强制实施模式的 Web 框架。这些软件框架在解释上有所不同,主要是在客户端和服务器之间划分 MVC 责任的方式 [12] 。早期的 MVC 框架采用了瘦客户端方法,几乎将整个模型、视图和控制器逻辑放在服务器上。在这种方法中,客户端向控制器发送超链接请求或表单提交,然后从视图接收完整且更新的网页;模型完全存在于服务器上。后来的框架允许 MVC 组件部分在客户端执行,使用Ajax 同步数据。常见的 MVC 框架有 Spring、Django 和 Ruby on Rails,接下来对其做简要的介绍。
Spring
Spring 框架是一个适用于 Java 平台的应用框架和控制反转容器。框架的核心功能可以被任何 Java 应用程序使用,但也有扩展用于在 Java EE(Java Enterprise Edition,Java 企业版)平台上构建 Web 应用程序 [7] 。该框架不强加任何特定的编程模型。在 Java 社区中,Spring 框架作为企业 JavaBean (Enterprise JavaBean,EJB) 模型的补充而变得流行起来。Spring 框架是免费的开源软件。
Django
Django 是一个基于 Python 的免费开源的 Web 框架,运行在 Web 服务器上 [13] 。它遵循模型-模板-视图(MTV)架构模式。由 Django Software Foundation(DSF)维护,这是一个在美国成立的独立组织,是一个非营利组织。Django 的主要目标是简化复杂的、数据库驱动的网站创建过程。该框架强调组件的可重用性和“可插拔性”、少量代码、低耦合、快速开发以及不重复自己的原则。Python 被广泛应用,甚至用于设置、文件和数据模型。Django 还提供了一个可选的管理创建、读取、更新和删除的界面,通过内省动态生成,并通过管理模型进行配置。一些使用 Django 的知名网站包括 Instagram [14]、Mozilla [15] 和Bitbucket [3]。
Ruby on Rails
Ruby on Rails(简称 Rails)是一个基于Ruby编程语言的开源 Web 应用程序框架 [16] ,采用 MVC 设计思想,旨在提高开发人员的生产力和代码的可维护性。Rails具有简单易用、开发效率高、强大的生态系统等特点和优势。其核心组件包括 Active Record、Action Controller 和 Action View,分别负责处理数据模型、HTTP 请求的控制和视图呈现。
Rails 提供了丰富的命令行工具和支持测试驱动开发的实践,同时支持 RESTful 设计风格和路由系统,使得设计和管理 Web 应用程序变得更加简单。Rails 的约定大于配置的设计理念,使得开发者可以快速上手并快速开发功能完善的 Web 应用程序。此外,Rails 拥有庞大的社区和丰富的扩展库,涵盖了各种领域的解决方案,开发人员可以轻松地集成第三方组件和服务,从而加速开发过程。总的来说,Ruby on Rails是一个功能丰富、开发效率高、生态系统健全的 Web 应用程序框架,适用于构建各种规模的 Web 应用程序和应用程序编程接口(Application Programming Interface,API)。其简单易用性和强大的功能使得许多开发人员选择 Rails 作为他们的首选框架,来快速、高效地开发和部署 Web 应用程序。一些使用 Ruby onRails 的知名网站包括 Github、airbnb [1] 和 shopify [17]。
架构特点
播报编辑
MVC框架适用于中大型项目,尤其是需要良好代码组织、长期维护和多人合作的系统,但在小型项目或性能敏感的场景下,其复杂性和性能开销可能不适合。其优缺点总结如下:
优点
- 1.清晰的结构:MVC将应用程序分为三部分——模型(Model)、视图(View)和控制器(Controller),使代码结构清晰,维护性好,便于开发人员理解和修改。
- 2.高可维护性:由于代码分离,修改业务逻辑时无需更改视图,视图的更改也不会影响控制器,便于模块化开发和后期维护。
- 3.可重用性高:模型和视图的解耦使得相同的模型可以在不同的视图中使用,减少了代码冗余,提高了代码复用性。
- 4.并行开发:MVC的分离允许团队中的开发人员并行工作,例如后端开发人员可以专注于模型和控制器,而前端开发人员专注于视图的实现。
缺点
- 1.增加了复杂性:对于简单的应用程序,引入MVC会增加不必要的复杂性,可能并不适合小规模项目。
- 2.学习曲线陡峭:MVC框架本身概念较为复杂,尤其对于新手开发者来说,理解并掌握这种模式可能需要一些时间。
- 3.视图和控制器之间的紧密耦合:虽然模型与视图解耦,但在某些实现中,控制器和视图的耦合性仍然较高,影响了代码的灵活性和可测试性。
- 4.性能问题:由于MVC框架将逻辑分为多个层次,导致数据在不同层次之间频繁传递,可能会导致一定的性能开销,特别是在高并发或需要即时响应的应用场景中。
外界评价
播报编辑
- Codecademy Team
MVC 是一种用于指导编程思维和组织程序文件的框架。开发者通常根据代码的功能为 MVC 的每个部分创建独立的文件夹,以确保代码结构清晰。这种基于功能划分应用程序的思想被称为“关注点分离”原则。在 Ruby on Rails 中,通常会看到每个 Rails 应用包含对应 MVC 部分的文件夹。MVC 不仅为开发提供了将想法转化为代码的框架,还能够在后期维护中帮助快速识别代码的功能。此外,MVC 推广的标准化组织方式使得其他开发者能够更轻松地理解和接手代码。编程中的一个重要方面是思考代码之间的交互方式,而与其他开发者协作也是关键技能。通过考虑应用程序如何适应 MVC 框架,可以提升开发效率,并使应用程序更具可维护性和扩展性。 [18]
- Great Learning Editorial Team
MVC框架非常方便组织和管理大规模的 Web 应用程序,特别适合多个开发者协作。同时,MVC 支持异步方法调用(Asynchronous Method Invocation,AMI),使得应用加载速度更快,且支持处理PDF、桌面小部件等功能。由于各部分独立,应用程序的修改和扩展变得更加灵活,开发过程也更快,可以多人并行工作。此外,MVC 在初期规划和后期维护中提供了良好的架构,减少代码重复。MVC 返回未格式化的数据,允许开发者使用多种视图引擎进行格式化,增强了组件的复用性。它还支持测试驱动开发(Test-driven Development,TTD),简化了测试和调试流程,并且易于开发 SEO 友好的应用。 [19]