作者:手机用户2502858383_827 | 来源:互联网 | 2024-11-30 07:43
模型-视图-控制器(MVC)模式在软件开发中极为普遍,不仅被广泛应用于Web框架,也在GUI客户端中得到应用。然而,这种模式的实际应用可能并非完全遵循原初的设计理念,有时更像是一个营销概念。本文将深入探讨MVC及其相关模式MVP、MVVM和MVA的异同,以及它们各自的应用场景。
模型-视图-控制器(MVC)模式在软件开发领域几乎无处不在,无论是Web框架还是GUI客户端,都能看到它的身影。然而,这种模式的实际应用往往与最初的设计理念有所偏差,有时甚至被视为一种营销策略。实际上,许多开发者和框架可能在使用类似于模型-视图-适配器(MVA)等其他模式。
MVC的起源
MVC模式最早出现在20世纪70年代,由Alan Kay和他的团队在Xerox Parc进行Dynabook和Smalltalk项目研究时提出。Trygve MH Reenskaug回忆说:“我提出了模型-视图-控制器模式,作为一种从多个视角解决用户控制其信息问题的方法。MVC引起了广泛的关注,但也有误解,甚至被用于实现计算机控制用户的相反目标。”尽管MVC未被收录在1994年出版的《设计模式》一书中,但Smalltalk的实现常被视为MVC的参考标准,因为它是首个被多个项目和开发者采用的实例。
2003年,Reenskaug重新评估了他的设计,将其细分为多种模式,称为MVC模式语言,包括:
- “模型/编辑器分离”,强调模型与用户界面的分离,使模型更贴近用户的心理模型,这是良好面向对象设计的重要特征。
- “输入/输出分离”,涉及通过控制器处理用户输入和通过视图展示模型信息,这一概念源自Smalltalk-80的实现。
- “任务工具”模式,即提供用户执行任务的工具,使其感觉像是直接与模型互动。
从设计模式的角度来看,控制器和视图组件可以视为模型的外观模式(Facade Pattern)。
基于架构原则的MVC解读
MVC模式也可从架构原则出发进行理解,主要包含两个步骤,直接对应Reenskaug提出的“模型/编辑器分离”和“输入/输出分离”:
- 在分层架构中,UI层应与底层模型分离,确保低层不了解高层,通过抽象实现松耦合,通常利用观察者模式从模型通知UI。
- 为了提高内聚性,需将用户交互与图形表现分离,因此UI层进一步划分为控制器和视图。两者均直接引用模型,位于同一层次,允许自由交互而无需观察者模式解耦。
这种设计解释了为何模型应在控制器和视图之下。不过,在现代环境下,严格区分控制器和视图的需求并不强烈。John Gossmann在2005年指出:“控制器在现代GUI开发中的角色变得模糊……它依然存在,但不再像1979年那样需要特别关注。”
MVC的演变
Model-View-Presenter(MVP)是MVC的一种变体,其类图与MVC相同,只是将“Controller”替换为“Presenter”。这一变化反映了实际操作上的区别:MVC中的控制器主要负责处理用户输入并更新模型,而MVP中的Presenter则侧重于更新模型,视图同样处理输入。
Model-View-ViewModel(MVVM)进一步将输入处理集成到视图中,彻底解耦模型与视图。不同于MVC中视图直接链接到模型,MVVM引入ViewModel作为中介,实现了视图与模型的间接通信。例如,ViewModel中常见的选择逻辑可以同时影响多个GUI组件。
MVVM模式的主要优势在于允许UI设计师在没有编程知识的情况下,通过XML定义视图,从而降低开发门槛。此外,MVVM也是Martin Fowler提出的被动视图(Passive View)模式的具体实现,旨在通过减少GUI组件中的逻辑,提高代码的可测试性。
模型-视图-适配器(MVA)
MVA模式彻底解耦了模型与视图,但并不排除视图中的逻辑处理。输入同样来源于视图,因此控制器在这里充当纯适配器的角色。当需要将数据库结构与用户界面分离时,适配器的作用尤为显著。
值得注意的是,MVA和MVVM在类图上是同构的,可以认为MVVM是针对WPF应用程序特化的MVA版本。
结论
MVC并不是一个界限分明的概念,不应将其视为固定不变的模式。在特定的开发环境中,如Android应用开发,MVC可能有明确的定义,但在大多数情况下,它更像是一个宽泛的概念。在设计系统时,盲目追求MVC或其他类似模式并无益处。更重要的是识别潜在的问题,并采取适当的措施解决。例如,UI与模型的紧密耦合可能导致任何一方的变更都需要调整另一方,增加维护成本。此时,可以通过观察者模式或其他机制主动解耦,或者选择不使用这些模式。