前言:
这周被分配到报告MVC、MVP与MVVM三种专案架构的比较,尽管之前在课堂上听过老师提过三者大致上的区别,但实际查找资料後,发现看越多反而对他们的印象感到越模糊和疑惑......囧
带着浓浓的疑惑询问老师,才知道原来业界对於三者的定义,其实也没有公认的标准答案,目前还蛮多有争议的点,所以感到疑惑是正常的! 瞬间有种安心感(才怪)
功课还是要完成的,只好将上网搜寻到,自己能理解的部分整理成简单的说明,以供未来慢慢再修改。以下就进入正题啦~
规划专案架构的目的
- 一般会考虑时程,人力,专案的规模,未来需求的变化等等,以在资源许可的范围内,规划合适的架构来进行开发。如果後续有很多功能要扩充,可以衡量是否要在前期做更有弹性的设计,多投入一些资源开发,节省未来维护的成本。简而言之,应用某种架构来开发程序的目的,是帮助开发者:因应未来功能增加或是需求变更,把程序码控制在较好维护和扩充的范围。
- 实现关注点分离: 简单来说就是一次只关注在一件事情上。比如在开发 App 时,明确的细分出谁负责Model的开发、谁负责View、谁负责Controller,各自将功能封装起来之後,就可以只专注在自己负责的事情上面,降低程序间耦合的程度。
MVC模式
简介
-
名词解释:
Model: 常译为「模型」,最小单位的元件或类,比如学生管理系统中的 「学生」,或游戏专题中的「GameObject」。负责操作资料的程序码都属於这一块,例如新增,修改,更新,删除资料,或者是从服务器上抓取资料等等。Model 不关心它会被如何显示或是如何被操作。
View: 常译为「视图」,举凡在画面上呈现一张图片,一个按钮,或者播放一段动画等等,只要是关於画面的呈现都可以归类到这一类。View负责发出正确的请求给Controller,以及当资料改变的时候,能够呈现给使用者正确的结果。
Controller: 常译为「控制器」,同时拥有 View 跟 Model,负责
1. 蒐集使用者於 View 中所输入的资料,并决定由哪一支程序进行处理。 2. 接收 Model 传回的资料,解析後传给 View 呈现 3. 进行整体流程控制,提供各式各样的逻辑来操作画面、例外处理与更新资料。
-
MVC 是三者间最早被提出与使用的设计模式,最早由Trygve Reenskaug在1978年提出,是全录帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。
-
在开发 Android App 时,XML 可以当作 View,Activity 和 Fragment 则担任 Controller。
-
以下图示流程为:
使用者操作 View(画面元件),View 接收事件并呼叫 Controller ,Controller 利用 Model 从资料库调度资料,等 Model 处理完资料後再通知 View 进行画面更新。
优点
-
提供结构,增强程序的可维护性
MVC 将一个功能区分成许多片段,让程序变得很容易维护。
-
代码重用
在MVC设计模式中,同一个 Model 可以被不同的 View 重用,所以大大提高了代码的可重用性,简化程序的开发。
-
容易识别
MVC的架构容易识别,可以让工程师快速掌握项目的结构
-
可协同作业
MVC将一个功能分成了三部分,因此多个工程师可以同时编写不同部分的程序码
缺点
-
要花费较多的时间进行前置规划
要做到将模型和显示器严格分离,需要花费许多时间规划如何将 MVC 套用到要开发的东西上,并且每个物件在使用之前都需要经过彻底的测试。
-
要管理较多文件
由於 MVC 将一个程序分成三个部分,所以意味着要管理比以前多的文件, 这样工作量便会增加。
-
View 与 Controller 间的连接过於紧密。
小结
- MVC 架构适合於大型系统,它可以分层且可以在实体层面切割为不同的机器或服务,只要彼此间具有适当的通讯协定即可。可以将一个专案的开发分成三个不同的角色来增加协同作业的效率。虽然在最初构建MVC模式框架时会花费一定的工作量,但从长远的角度来看,它会大大提高後期软件开发的效率。
- 尽管过去MVC模式并不适合小型甚至中等规模的应用程序,因为程序规模小难定义哪些部分要划分到Controller,哪些又要划分到 View 或 Model,强要使用MVC的话,反而导致事倍功半。但现在多数软件设计框架,能直接快速提供MVC骨架,供中小型应用程序开发。
MVP模式
简介
MVP 把 Activity 中的 UI 逻辑抽象成 View 接口,把业务逻辑抽象成 Presenter 接口,Model 类还是原来的 Model。
-
名词解释:
Model: 和在 MVC 中一样,只负责对数据进行处理。
View: View通常来说是由Activity、Fragment实现的,View会包含一个或多个Presenter的引用来满足View的业务逻辑。View和Presenter的交互是双向的,即View层可以调用Presenter的逻辑方法,Presenter也可以控制View的显示。在MVP模式里,View只应该有简单的Set/Get的方 法,用户输入和设置介面显示的内容,除此之外就不应该有更多的内容。
Presenter: 作为 Model 和 View 的桥梁,负责从 Model 拿到数据进行处理并返回给 View。但 Presenter 和其他两层的沟通是通过接口协议进行的,从而使得在变更 View 或 Model 的时候,可以保持Presenter的不变,所以每个 Presenter 中通常会包含一个或多个接口协议。
-
和 MVC 不同的地方,MVP 架构更重视元件之间的分离。View 并不能直接对 Model 进行操作,且 Model 不再通知 View 进行更新,而完全透过 Presenter 来进行沟通,成为两个独立的单元。主要的程序逻辑在Presenter里实现。
-
和 MVVM 不同的地方,MVP 架构需要让 View 与 Presenter 彼此知道对方,Presenter 会想跟View说,何时要做什麽;而 MVVM 模式里,View 知道 ViewModel,但 ViewModel 不想知道 View,它关心的是数据。必须透过绑定後,他们才会有连动。
-
可以在Model和View都没有完成的时候,就通过编写Mock Object(即实现了Model和View的接口,但没有具体的内容)来测试Presenter的逻辑。
-
以下图示流程为:
使用者操作画面时,View 接收事件交给 Presenter,Presenter 操作 Model 处理资料,Model 处理完资料後通知 Presenter,再由 Presenter 通知 View 更新画面。
优点
-
Model 与 View 完全分离:
因此可以修改 View 而不影响 Model,达到较高的可维护性,方便重用,利於单元测试。
-
更高效地使用 Model:
因为所有的交互都发生在 Presenter 内部
-
可以将一个 Presenter 用於多个 View,而不需要改变 Presenter 的逻辑。这个特性非常的有用,因为 View 的变化总是比 Model 的变化频繁
-
职责的区分:
由於逻辑放到 Presenter 中,Activity 和 Fragment 可以专心处理自己的生命周期,和负责管理介面的操作和显示,也可以脱离用户接口来测试这些逻辑(单元测试)
-
使用 interface 互相操作:
实作上会在各元件间加入 interface,用 interface 来规范方法。彼此间互相注入 interface 来进行操作来降低耦合性。相对的,由於依赖 interface 提供的方法来操作,需求修改时,interface 和实作需要一起修改。
缺点
- View 的渲染放在Presenter中,所以 View 和 Presenter 的交互会过於频繁。如果 Presenter 过多地渲染 View,往往会使得它与特定的 View 的联系过於紧密。
小结
- MVP 架构适合集中由程序码决定 View 动作的应用程序,而 View 只需要实作特定的介面即可,不需要太复杂的工作,但 Presenter 则可能会受限於 View 介面的动作,而无法做更进一步对 View 的控制。
MVVM模式
简介
-
名词解释:
Model: 管理所有的资料来源,例如API、资料库和SharedPreference,当ViewModel来请求资料时从正确的来源取得资料并回传。
View: 单纯的视觉元件,像是按钮、文字标签等等,本身不做逻辑处理,只负责显示UI。当使用者跟UI有互动时,用 Data Binding 将指令传给 ViewModel 处理,View 一看到 ViewModel 的资料有更新,就会跟着一起更新。
ViewModel: 比较像是 View 的一个代理程序,负责接收 View 的指令并直接对 Model 做沟通请求资料,再将取得的资料整理成易於阅读的格式,保存起来供 View 使用。 ViewModel 也可以作为和外部系统的代理程序,例如 Web Service 或是 REST Service 等等。
-
和 MVC 不同的地方,就是 ViewModel 和 View 的黏合度比较高,因为 View 必须要透过 ViewModel 才可以取得 Model,而 ViewModel 又必须要处理来自 View 的通知讯息,所以虽然职责一样分明,但是却不像 MVC 那样可以扩展到整个系统元件都能用。
-
和 MVP 最不同的地方,ViewModel 并不使用callback的方式来通知 View,而是用Observer pattern(观察者模式)的概念,由 View 来订阅(subscribe) ViewModel 中它要的资料,并在资料资料改变时,让 UI 自动更新。简单来说,MVVM 使用双向 Data binding,就是view一有改变,viewModel也会跟着变;而viewModel改变,view也会跟着变。
注: Data binding 是官方提供的library,专门用来处理View的更新。
-
以下图示流程为:
把资料存在 ViewModel 中,View 观察 ViewModel 中的资料。当使用者操作画面时,View 接收事件交给 ViewModel,ViewModel 操作 Model 处理资料,Model 处理完资料後通知 ViewModel 更新资料。由於 View 观察 ViewModel 中的资料,所以资料更新後 View 会收到更新,并更新画面。
优点
-
资料驱动:
事件都透过资料的变化来触发,资料成为最关键的因素。
-
下层元件不需要知道上层元件:
在 MVC / MVP 中,都需要有 View 的引用来更新 UI。但在 MVVM 中,由 View 主动观察资料,在资料变化後收到通知而自动更新, ViewModel 不需要知道 View 是谁。
-
职责分离:
ViewModel 中可以减少大量通知 View 的程序码,专心的管理流程。而 Activity 和 Fragment 不用储存资料状态,可以专心管理介面的操作和显示,并妥善控制生命周期。
缺点
- 资料系结使得 Bug 很难被除错。当看到介面异常了,有可能是 View 的程序码有 Bug,也可能是 Model 的程序码有问题。资料系结使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那麽容易了。
- 对於过大的专案,因为 model 很大,资料系结需要花费更多的记忆体,不利於内存的释放。
- 对於大型 webapp,所有逻辑和数据都在ViewModel里,ViewModel会越来越复杂。
小结
- MVVM 架构适合像 XAML 这种与程序码无关 (code ignorance) 的使用者介面设计,只要 View 中下特定的指令与 ViewModel 串接,就可以享有 ViewModel 沟通的功能,而 ViewModel 只需做一些特别的介面实作,即可平顺的和 View 沟通。
- 一般来讲,不太需要处理复杂逻辑运算的专案才会使用MVVM。
下周目标
- 周一报告後正式开启了期末专题发表的倒数计时,这次有幸能参与实习组的课题,也因此见识到策略长、技术长和专案PM等人,从各自的专业对我们三人提出的专案雏形,进行二度发想和最後收敛的过程。开完会後,对於本来模糊的专题我们似乎能看的更清晰些。
- 下周的目标希望能用Xcode初步刻出我们App最核心的两三个页面,并顺利串接上Google提供的API。