MVC、MVP、MVVM架构

试想一下这种场景:初学者想做一个简单的小游戏,由于没有做任何代码结构的分层,可能会将游戏逻辑、角色属性和 ui 交互都混在一起编写。当我们需要增加或修改任何功能或界面时,牵一发而动全身,可能会需要修改整个脚本,容易出现错误和影响其他功能,代码阅读也会更加困难。为了解决这些问题,可以采用一些合适的软件架构模式,以更好地组织和管理游戏代码。今天我们就来了解几个常见的软件架构模式。

MVC架构

MVC架构简介

MVC(Model-View-Controller)是一种经典的软件架构模式,广泛用于各种应用程序,包括游戏开发。MVC将应用程序分成三个主要部分,每个部分有不同的责任,以实现代码的分离和可维护性。这三个组成部分分别是:

  • Model(模型)

    • 模型表示应用程序的数据和业务逻辑,是应用程序的核心。
    • 它负责数据的存储、处理和更新,以及对外提供数据的访问接口。
    • 模型通常不直接处理视图和用户输入,是独立的数据层。
    • 在游戏中,Model可以表示游戏中的角色、物体、游戏规则、关卡数据等。
  • View(视图)

    • View代表用户界面,是模型的可视化表示。
    • 视图负责呈现数据给用户并接受用户输入。
    • 视图不包含应用程序的业务逻辑,仅负责显示数据,它从模型中获取数据,并将其呈现在屏幕上。
    • 视图是被动的,它不直接处理用户输入,而是将输入传递给控制器进行处理。
    • 在游戏中,View可以是游戏中的UI元素、画面渲染等。
  • Controller(控制器)

    • 控制器是应用程序中的决策者,充当了模型和视图之间的中介。
    • 控制器负责处理用户的输入,并根据输入更新模型和视图,协调Model和View之间的交互。
    • 在游戏中,Controller可以处理玩家的输入、游戏规则的执行等。

MVC工作流程

MVC模式的工作流程通常如下:
MVC

  • 用户与View进行交互,例如,点击按钮或输入文本,这些操作触发了View中的相关事件。
  • View感知到这些事件后,通常通过事件处理程序或回调机制通知Controller进行处理。
  • Controller接收到View传递的事件后,开始处理相关业务逻辑,根据用户的操作更新Model中的数据或调用Model中的业务逻辑。
  • Model的业务数据改变触发相应事件,通知View业务数据已经发生改变。
  • View捕获到Model发出的数据改变事件,重新获取数据并更新用户界面。

MVC的优点

  • 代码分离 :MVC将应用程序分成三个独立的组件(模型、视图和控制器),每个组件都有自己的责任和功能。这样可以实现分离关注点,让代码模块更清晰、结构更合理,提高代码的可读性和可维护性。
  • 代码重用 :由于MVC的分离性,不同部分的代码可以更容易地进行重用。模型和视图可以在不同场景或不同应用中重用,而控制器可以处理不同的用户输入,从而减少了重复编写代码的情况。
  • 可维护性 :由于模块化的设计,可以更容易定位和修复问题,以及进行功能扩展。
  • 可扩展性 :MVC的分层结构使得应用程序更易于扩展。添加新的功能或模块时,可以通过增加模型、视图或控制器来实现,而不需要修改整个应用程序的代码。
  • 团队协作 :MVC将应用程序拆分成三个部分,使得不同的团队成员可以独立地并行开发和测试各自的组件。这样有利于团队协作,提高项目的开发效率。
  • 易于测试 :MVC架构使得应用程序的不同部分可以更容易地进行单元测试。因为模型、视图和控制器的职责分离,测试可以更加集中和专注。

Unity项目中的MVC思想

注意,Unity项目开发中的MVC可能并不是严格的传统MVC模式,而是一种变种或简化的方式,因为游戏开发不像网站开发那样,Model,View,Controller在游戏这个领域里还没有很清晰的定义,不同游戏类型本身的软件架构可以相差很远,而且游戏的Object之间有大量的交互,所以纯粹的MVC并不适用,我们这里讲的主要是一种逻辑分离的思想,具体运用需要根据项目的需求和复杂性进行调整。

在Unity开发中,MVC思想可以用于分离游戏的数据、用户界面和控制逻辑,以提高代码的可维护性和可读性。

  • Model(模型) :在Unity中,模型可以是代表游戏中的各种数据和业务逻辑的脚本类。例如,角色属性、游戏状态、游戏规则、关卡数据、道具等数据和逻辑都可以被归类为模型。使用C#类来定义Model,这些类包含数据成员和方法来操作数据,但不包括Unity的MonoBehaviour。
  • View(视图) :在Unity中,视图可以是代表游戏场景中的物体、UI元素或预制件,用于展示模型中的数据。Unity中的Canvas、UI元素、3D模型等可以作为View的一部分。View负责将Model的数据呈现给用户,并将用户输入传递给Controller。
  • Controller(控制器) :在Unity中,控制器可以是脚本类,负责处理用户的输入,并根据输入来更新模型和视图,协调Model和View之间的交互,实施游戏逻辑。Controller可以处理用户输入,如鼠标点击、键盘输入等,然后更新Model中的数据或调用Model中的方法来执行游戏逻辑。它还可以更新View以反映Model的变化。

此外,可以使用事件系统或委托来实现Model、View和Controller之间的通信。事件可以用于通知不同部分之间的状态变化,例如,当玩家得分时,Controller可以触发一个事件,View可以订阅该事件以更新分数显示。

在Unity项目中采用MVC思想可以带来一些好处:

  • 代码组织 :Unity项目通常会变得复杂,特别是在游戏开发中,有大量的游戏对象、脚本和交互逻辑。采用MVC思想可以帮助更好地组织代码,将模型、视图和控制器分离开来,使得代码结构更清晰,易于阅读和维护。
  • 可维护性 :MVC的分层结构使得修改和扩展游戏功能变得更加容易。如果需要更改游戏逻辑或UI展示,只需要关注对应的控制器或视图,而不需要影响整个游戏代码。
  • UI管理 :在Unity中,UI通常是一个重要的部分,MVC思想可以帮助将UI和逻辑分离开来。通过采用MVC,我们可以更好地管理UI的展示和交互逻辑。当需要添加新功能或修改UI显示时,只需修改对应的模型、视图或控制器类,不会影响其他部分的代码。
  • 数据共享 :在Unity中,MVC可以帮助我们实现数据的共享和重用。通过将数据逻辑放在模型中,并在不同的场景或游戏对象中共享模型,可以使得数据在整个游戏中保持一致性。
  • 耦合性低 :角色的数据和行为被封装在模型中,视图和控制器只负责显示和交互,降低了代码耦合度,增加了代码复用性和扩展性。

总的来说,MVC思想在Unity项目中可以提供更好的代码组织、可维护性和扩展性,使得项目开发更加高效和有条理。但要根据项目的规模和需求来选择是否采用MVC,对于小型项目可能并不需要过度划分MVC架构,而在大型或复杂项目中,采用MVC可以带来更多的好处。

MVP架构

MVP架构简介

MVP(Model-View-Presenter)是从MVC演变而来的一种架构模式。在MVC的基础上,MVP强调Model与View之间的隔离,两者互不感知。MVP模式的主要组成部分如下:

  • Model(模型)
    • Model代表应用程序的数据和业务逻辑。
    • Model包含数据的存储、检索、更新和应用程序的核心业务逻辑。
    • Model不直接与用户界面交互,通常是一个独立的数据层。
  • View(视图)
    • View负责呈现数据给用户,并接受用户输入。
    • View通常包括用户界面元素,如窗口、按钮、文本框等。
    • View是用户界面的可视表示,但不包含与数据处理或业务逻辑相关的代码。
  • Presenter(主持人)
    • Presenter充当Model和View之间的中介,负责协调用户界面逻辑,将Model的数据呈现给View,并处理用户输入。
    • Presenter包括以下方面的工作:
      • 从Model检索数据并准备数据以便呈现在View上。
      • 接受用户输入并将其传递给Model以执行相应的操作。
      • 处理用户界面逻辑,例如数据格式验证、格式转换、用户输入提示等。
    • Presenter不应包含任何与用户界面视觉表示相关的代码。

MVP工作流程

MVP模式的工作流程通常如下:
MVP

  • 用户对界面进行操作,例如点击按钮或输入文本,触发View的相关事件。
  • View感知到这些事件之后,通过特定的接口或回调方法,通知Presenter进行处理。这是View与Presenter之间的通信。
  • Presenter接收到来自View的事件通知后,开始处理业务逻辑。这可能涉及从Model中检索数据、执行特定操作,验证数据,或进行其他业务相关的任务。
  • 如果Presenter需要更新数据,它将通过Model的接口来对数据进行更新或请求必要的数据。
  • 当Model中的数据发生变化时,Model会通知Presenter,通常通过观察者模式或其他通知机制。
  • Presenter收到Model数据变化通知后,调用View暴露的接口更新用户界面,使用户能够看到数据的变化。

MVP的优点

MVP模式具备MVC模式的优点,且相比于传统的MVC模式引入了一些额外的优点:

  • 松耦合度的增加 :在MVP中,View和Model之间不直接通信,而是通过Presenter进行协调。这降低了View和Model之间的耦合度,使它们可以独立开发和维护。这使得更容易替换View或Model,而不会影响整个应用程序的结构。
  • 更好的分离关注点 :MVC常常会因为V和M的耦合性太强而渐渐产生问题,导致C渐渐失去作用,但MVP模式视图和模型完全分离。
  • 更容易实现多视图 :MVP模式使得更容易实现多个不同的视图,共享相同的Presenter。这可以在不重复编写业务逻辑的情况下创建多个用户界面,从而提高了代码的复用性。
  • 逻辑的集中管理 :在MVP中,Presenter充当了中央控制器,负责管理用户界面逻辑和业务逻辑。这样,所有与用户界面相关的逻辑都集中在一个地方,而不分散在控制器和视图之间。这有助于更好地组织代码和降低复杂性。
  • 提高用户界面的可定制性 :由于MVP模式将用户界面和业务逻辑分开,更容易调整和自定义用户界面的外观和行为,而不需要修改底层逻辑。
  • Model设计更灵活 :所有交互都在P中实现,M的设计可以更加灵活,有利于M的高效使用。

MVVM架构

MVVM架构简介

MVVM(Model-View-ViewModel)也是MVC的演变而来,通常用于构建用户界面(UI)驱动的应用程序。它在传统的MVC模式基础上将Controller层变成了ViewModel层,MVVM代表Model-View-ViewModel。MVVM强调数据绑定,从而省去了模型数据改变后通知数据更新的步骤。MVVM模式由以下三个主要组成部分组成:

  • Model(模型)
    • Model代表应用程序的数据和业务逻辑。
    • Model包含数据和方法,用于处理数据的存储、检索、更新和应用程序的核心业务逻辑。
    • Model通常不直接与用户界面交互,而是为ViewModel提供数据。
  • View(视图)
    • View负责呈现数据给用户并接受用户输入。
    • View通常包括用户界面元素,如窗口、按钮、文本框等。
    • View通过数据绑定将自己与ViewModel连接,ViewModel可以提供数据和逻辑,以便View进行呈现。
  • ViewModel(视图模型)
    • ViewModel充当Model和View之间的中介,负责处理用户界面逻辑,将Model的数据呈现给View,并处理用户输入。
    • ViewModel包括以下方面的工作:
      • 数据绑定:ViewModel提供要在View中显示的数据,并与View建立数据绑定。这样,当Model中的数据更改时,View会自动更新。
      • 命令处理:ViewModel包含命令,例如按钮点击事件,以执行与用户交互相关的操作。
      • 数据验证:ViewModel可以包括验证逻辑,以确保用户输入的有效性。
      • 与Model的交互:ViewModel与Model交互,检索、更新或操作数据。
      • 处理用户输入:ViewModel接受用户输入,执行相应的操作,例如更新Model中的数据或触发特定的命令。

MVVM工作流程

MVVM模式的工作流程通常如下:
MVVM

  • 界面渲染完毕后,ViewModel会将View和Model按照开发时声明的方式进行双向绑定。
  • 用户对界面进行操作,触发View中的相关事件。
  • View接收用户输入,并将其传递给ViewModel。
  • ViewModel调用Model的接口处理业务逻辑。
  • Model数据发生变化后,通知ViewModel,View通过数据绑定自动将更新后的数据呈现给用户,以反映最新的数据状态。所以Model内容改变后,用户界面会立即更新,无需额外操作。

MVVM的优点

MVVM相对于传统的MVC和MVP模式又具有一些额外的优点,例如:

  • 自动数据绑定 :MVVM借助数据绑定机制,实现了视图与视图模型之间的双向数据绑定。这使得用户界面元素能够自动更新以反映视图模型中的数据变化,而不需要编写手动的更新逻辑。这提高了代码的简洁性和可维护性。
  • 适应现代UI :MVVM适用于现代的用户界面开发,包括Web应用、桌面应用和移动应用。其自动数据绑定和响应式特性使其非常适合创建交互性强、实时性要求高的应用程序。
  • 多平台通用性 :MVVM模式适用于不同平台的应用程序开发,因为其核心概念是通用的。这允许开发人员在不同平台上使用相似的架构模式。

对比MVC、MVP、MVVM

从上面对MVC、MVP、MVVM的介绍可以明显地看出,它们呈现递进关系,是不断优化的软件架构模式。MVP在MVC的基础上实现了M和V的解耦,MVVM在MVP的基础上实现了数据绑定。它们在不同方面具有不同的优劣势,我们可以简单进行一下三者的总结和对比。

MVC的优缺点

MVC优点

  • 广泛使用 :MVC是一种经典且广泛使用的架构模式,开发者们对MVC非常熟悉,它在许多传统的Web和桌面应用中得到了广泛应用。
  • 分离关注点 :MVC将应用程序分成三个独立的组件,分别负责数据处理、界面展示和用户输入处理,使代码更易于理解和维护。
  • 代码复用 :由于MVC的分离性,不同部分的代码可以更容易地进行重用,使得开发效率提高。
  • 成熟的生态系统 :MVC有丰富的工具和框架支持,如Django、Ruby on Rails、Spring等。

MVC缺点

  • 耦合度较高 :在MVC中,View和Controller之间通常是紧耦合的,Controller直接处理View的事件,这样可能导致代码依赖性较高。且MVC并未限制数据流,Model和View可能有耦合。
  • Controller负担较重 :在MVC中,Controller承担了大部分的用户输入处理和业务逻辑,随着应用复杂度的增加,Controller可能会变得庞大和复杂。

MVC适用场景和示例

  • Web应用:MVC是Web应用中最常见的架构模式,例如ASP.NET MVC框架。
  • 桌面应用:传统的桌面应用程序,如使用Java Swing或Windows Forms等,也可以采用MVC模式。
  • MVC在Unity中通常用于较为简单的项目或小型游戏,特别是当项目的UI和逻辑较为简单,或者开发者对MVC较为熟悉时。
  • 在Unity中,MVC模式可以通过自定义脚本组件来实现。模型通常代表游戏中的数据和业务逻辑,视图负责展示数据给用户,控制器处理用户输入并更新模型和视图。

MVP的优缺点

MVP优点

  • 更强的分离 :相较于MVC,MVP通过引入Presenter,进一步增强了模型、视图和控制器之间的分离,使每个部分更加独立。
  • 可测试性 :Presenter是业务逻辑的中心,易于进行单元测试,有助于提高代码质量。
  • 框架不依赖 :MVP模式不依赖具体的框架,适用于不同的开发环境。

MVP缺点

  • 代码量增加 :引入Presenter可能导致代码量增加,但这有助于更好的分离关注点。
  • 较少的自动化 :相对于MVVM,MVP通常需要更多手动的工作来更新视图,因为没有自动数据绑定机制。

MVP适用场景和示例

  • 适用于桌面应用程序、一些前端框架和具有较强用户交互的应用。
  • 用于需要更好的分离关注点和可测试性的应用,其中模型负责数据和业务逻辑,视图负责用户界面,主持人负责处理用户输入和协调模型和视图之间的通信。

MVVM的优缺点

MVVM优点

  • 强大的数据绑定 :相较于MVP,MVVM引入了自动数据绑定,使视图与视图模型之间的数据同步自动完成,简化了用户界面的更新。
  • 更好的分离 :相较于MVC,MVVM将模型、视图和视图模型更清晰地分离,降低了耦合度。
  • 适应现代UI :MVVM非常适用于需要响应性和实时性的应用程序,如单页应用程序(SPA)和移动应用。

MVVM缺点

  • 学习曲线 :相对于MVC和MVP,MVVM的学习曲线可能较陡,尤其是对于初学者来说,掌握数据绑定和ViewModel的概念可能需要一些时间。
  • 不适合所有场景 :MVVM更适合复杂的用户界面和需要实时数据更新的应用程序,但对于简单的应用程序可能显得过于繁琐。

MVVM适用场景和示例

  • 响应式UI:MVVM特别适用于需要响应式UI的项目,例如使用WPF或Vue.js等前端框架。当UI与数据交互较为复杂,或者需要实现数据驱动的UI时,MVVM是一种较好的选择。
  • 数据驱动应用:当应用的主要逻辑是数据驱动时,MVVM可以更好地组织和管理数据和界面的交互。
  • 复杂的前端应用:对于大型、复杂的前端应用,MVVM能够帮助开发者更好地管理代码,并保持UI和数据的同步。

总结

MVC适用于传统的Web和桌面应用,MVP适用于分离性要求更高的Web和桌面应用,MVVM适用于响应式UI和数据驱动的应用。在Unity项目开发中,选择使用MVC、MVP还是MVVM取决于项目的需求和复杂性。对于较为简单的项目或小型游戏,MVC或MVP可能足够满足需求。而对于复杂的项目或需要响应式UI的场景,MVVM提供了更好的代码组织和管理方式,使得UI和数据的交互更加清晰和灵活。在选择使用哪种架构模式时,要根据项目的需求和复杂性来进行考虑,并结合团队成员的熟悉程度和技术栈来决定使用何种模式。在实际项目中,也可以根据需求的变化来灵活选择和调整架构模式。