第9章 · 播客 第8集
软件架构设计 · MVC与MVP辨析
🎙️ 本集播客:第8集:MVC 的出身(Reenskau 1979、SmallTalk)与关注点分离思想、三个自治视图的问题、Model/View/Controller 职责交互链;MVP 的关键区别(View 不直接使用 Model、Presenter 依赖 IView 接口)与四优两缺——练习题第五、六题原产地。 语音由微软 Edge 神经网络语音预生成(女声·晓伊,男声·云希)。点击下方任意对话可直接从该句开始播,当前句朗读时下一句已预先加载,无缝衔接。
明
阿明
师姐,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——练习题第七、八、九题全埋在那两集里。