第9章 · 播客 第8集

软件架构设计 · MVC与MVP辨析

🎙️ 本集播客第8集:MVC 的出身(Reenskau 1979、SmallTalk)与关注点分离思想、三个自治视图的问题、Model/View/Controller 职责交互链;MVP 的关键区别(View 不直接使用 Model、Presenter 依赖 IView 接口)与四优两缺——练习题第五、六题原产地。 语音由微软 Edge 神经网络语音预生成(女声·晓伊,男声·云希)。点击下方任意对话可直接从该句开始播,当前句朗读时下一句已预先加载,无缝衔接。
🎙️ 第9章播客 第8集
⬇ 下载本集 点击播放
阿明
师姐,MVC 我写代码天天用,但这章的讲法好像跟工程里的不太一样?
小雅
本章口径以原文为准,先记出身。MVC 全名是 Model View Controller,是模型、视图、控制器的缩写,它是分层架构风格的一种。MVC 是由挪威的计算机专家 Trygve M.H. Reenskau 于 1979 年提出的软件架构模式,MVC 最初用于 SmallTalk。国籍挪威、年份 1979、语言 SmallTalk,三个细节都能单独出题。
小雅
MVC 提出的基本思想是进行关注点分离。一个典型的人机交互应用具有三个主要的关注点:数据在可视化界面上的呈现、UI 处理逻辑和业务逻辑。反面教材是传统的自治视图模式,即将与 UI 相关的逻辑都定义在针对视图的相关元素的事件上,将三者混合在一起,势必带来一系列问题,原文列了三条。
小雅
第一,业务逻辑是与 UI 无关的,应该最大限度地被重用;由于业务逻辑定义在自治视图中,相当于完全与视图本身绑定在一起,如果我们能够将 UI 的行为抽象出来,基于抽象化 UI 的处理逻辑也是可以被共享的,但定义在自治视图中的 UI 处理逻辑完全丧失了重用的可能。第二,业务逻辑具有最强的稳定性,UI 处理逻辑次之,而可视化界面上的呈现最差,比如我们经常会为了更好地呈现效果来调整 HTML;如果将具有不同稳定性的元素融为一体,那么具有最差稳定性的元素决定了整体的稳定性。第三,任何涉及 UI 的组件都不易测试,UI 是呈现给人看的,用机器来模拟活生生的人对组件实施自动化测试不是一件容易的事,自治视图严重损害了组件的可测试性。
阿明
所以正是为了解决这三个问题,需要用关注点分离把可视化界面呈现、UI 处理逻辑和业务逻辑三者分离出来。那三个角色怎么分工?
小雅
分工与协作,原文三段话逐句抠。第一,Model 是对应用状态和业务功能的封装,可以将它理解为同时包含数据和行为的领域模型。Model 接受 Controller 的请求并完成相应的业务处理,在状态改变的时候向 View 发出相应的通知。第二,View 实现可视化界面的呈现并捕捉最终用户的交互操作,例如鼠标和键盘的操作。第三,View 捕获到用户交互操作后会直接转发给 Controller,后者完成相应的 UI 逻辑。如果需要涉及业务功能的调用,Controller 会直接调用 Model。在完成 UI 处理后,Controller 会根据需要控制原 View 或者创建新的 View 对用户交互操作予以响应。
阿明
练习题第五题问 Model 的主要职责,正确选项是「封装应用状态和业务功能,状态改变时向 View 发出通知」。干扰项「实现可视化界面的呈现并捕捉用户交互操作」是 View 的,「完成 UI 逻辑处理,控制原 View 或创建新 View」是 Controller 的——三个职责各归各位就没错。
小雅
这道题就是把三个角色的职责打乱重配,你只要记住交互链条就能全灭:用户操作被 View 捕捉、转给 Controller、Controller 调 Model、Model 状态变了通知 View、Controller 再控制视图响应。还有一个细节别漏:MVC 模式中元素之间「混乱」的交互主要体现在允许 View 和 Model 直接进行「交流」——在 MVC 中 View 会直接从 Model 中读取数据而不是通过 Controller。这句话是引出 MVP 的桥。
小雅
MVP 登场。MVP 的全称为 Model-View-Presenter,Model 提供数据,View 负责显示,Controller/Presenter 负责逻辑的处理。MVP 是从经典的模式 MVC 演变而来,它们的基本思想有相通的地方。显著的区别就在刚才那句:MVC 允许 View 和 Model 直接交流,这在 MVP 模式中是不允许的。在 MVP 中 View 并不直接使用 Model,它们之间的通信是通过 Presenter 即 MVC 中的 Controller 来进行的,所有的交互都发生在 Presenter 内部。
阿明
练习题第六题就是考这个:MVP 中 View 不直接使用 Model,通信通过 Presenter 进行。干扰项「MVP 允许 View 和 Model 直接通信」说的恰恰是 MVC。
小雅
MVP 还有一处高级设计要记:它不仅仅避免了 View 和 Model 之间的耦合,还进一步降低了 Presenter 对 View 的依赖。Presenter 依赖的是一个抽象化的 View,即 View 实现的接口 IView,这带来的最直接的好处,就是使定义在 Presenter 中的 UI 处理逻辑变得易于测试。由于 Presenter 对 View 的依赖行为定义在接口 IView 中,我们只需要一个实现了这个接口的 View 就能对 Presenter 进行测试。IView 这个接口名要记住。
小雅
MVP 的优点四条:第一,模型与视图完全分离,我们可以修改视图而不影响模型;第二,可以更高效地使用模型,因为所有的交互都发生在一个地方即 Presenter 内部;第三,我们可以将一个 Presenter 用于多个视图而不需要改变 Presenter 的逻辑,这个特性非常有用,因为视图的变化总是比模型的变化频繁;第四,如果我们把逻辑放在 Presenter 中,那么我们就可以脱离用户接口来测试这些逻辑,也就是单元测试。
小雅
缺点原文给了两段:由于对视图的渲染放在了 Presenter 中,所以视图和 Presenter 的交互会过于频繁;还有一点需要明白,如果 Presenter 过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密,一旦视图需要变更,那么 Presenter 也需要变更了。比如说,原本用来呈现 HTML 的 Presenter 现在也需要用于呈现 PDF 了,那么视图很有可能也需要变更。
阿明
四优两缺。优点里「一个 Presenter 用于多个视图」和「脱离用户接口做单元测试」最常考,都源于 Presenter 只依赖 IView 接口。
小雅
本集必背:MVC 是 Reenskau 1979 年提出、最初用于 SmallTalk、属分层架构风格、基本思想是关注点分离;三个关注点是数据可视化呈现、UI 处理逻辑、业务逻辑;Model 封装应用状态和业务功能、状态改变时通知 View,View 负责呈现并捕捉交互,Controller 完成 UI 逻辑、直接调用 Model、控制原 View 或创建新 View;
小雅
MVC 中 View 和 Model 可以直接交流,MVP 不允许——View 不直接使用 Model,通信通过 Presenter,所有交互发生在 Presenter 内部;Presenter 依赖抽象化的 IView 接口,故易测试;MVP 四优——模型视图完全分离、高效使用模型、一个 Presenter 多个视图、可单元测试;缺点是视图和 Presenter 交互过于频繁、Presenter 与特定视图可能绑得过紧。
阿明
MVC 和 MVP 这对辨析总算焊死了。下一集该 SOA 了?
小雅
对,而且是连续两集的大块:先讲 SOA 的三个定义、设计原则五条、服务构件与传统构件的四点区别、关键技术 UDDI/WSDL/SOAP/REST——练习题第七、八、九题全埋在那两集里。