在师兄带领下给一个创业公司开发 APP,所以看下关于项目架构 MVC 。
在网上找张图来展示 MVC 的架构模式,如下图:
【图片来至于网络】
MVC 简介
从文字上来进行显示,MVC(Modal View Controller)
模型、视图和控制器。使用 MVC 的方法目的是:实现数据和视图分离,来减少在创建过程中的耦合。
由上图可以看出:
View
上面显示的数据来至于Model
Model
里面的数据如果有修改,就会带着 View
显示就会随之更改。Controller
初始化 Model
, 并读取 Model
来传递给 View
来进行显示。
Modal
模型对象:
Model
数据模型来封装应用的数据,在其中包含操作和处理数据的逻辑和相关运算。在我们队视图进行修改或者创建数据的操作,就会通过视图控制器对象传达出去,最终会创建和修改 Model
对象。模型对象更改时,它通知控制器对象,控制器对象更新相应的视图对象。
View
视图对象:
在iOS应用程序开发中,所有的控件、窗口等都继承自 UIView
,对应 MVC
中的 V。UIView
及其子类主要负责 UI 的实现,而 UIView
所产生的事件都可以采用委托的方式,交给 UIViewController
实现。
Controller
控制器对象:
控制器对象是在对视图操作相关的解释,作用是将更改或者是刷新的数据来传递给模型对象。在模型对象进行更改时,当前控制对象就会把新的数据模型传达给视图,视图加载数据来进行显示在界面上。
在编码过程中一个或者十多个视图对象和一个多个模型对象之间,控制对象负责充当媒体。控制器对象目的是管理模型对象和视图对象之间程序,来使视图对象数据和模型对象数据达到一致。在程序的生命周期控制对象也具有很重要的地位。
不同的 UIView
,有相应的 UIViewController
,对应 MVC
中的 C
。例如在 iOS
上常用的 UITableView
,它所对应的 Controller
就是UITableViewController
。
MVC 实例应用
在和师兄一起做的项目 HiZher
分享圈中,需要对加载后的数据进行相关的展示。在这里使用 MVC 可以实现很好数据和视图分别管理。
- Model 模型创建
1 | //NewsMessageModel.h 文件 |
- View 视图对象
1 | //NewsMessageCell.h 文件 |
- Controller 控制创建
1 |
|
上图展示使用
MVC
的模式来对消息的展示,但是目前没有从服务器获取的数据。所以数据的初始化就家采用加载本地的数据。
MVC
缺点
MVC 是一个用来组织代码的权威范式,也是构建 iOS App 的标准模式。在 MVC 下,所有的对象被归类为一个 model,一个 view,或一个 controller。Model 持有数据,View 显示与用户交互的界面,而 View Controller 调解 Model 和 View 之间的交互。然而,随着模块的迭代我们越来越发现 MVC 自身存在着很多不足。
1)Controller 越来越重:
就像我们在做的 app 中模型数据一般都很简单,不涉及到复杂的业务数据逻辑处理,客户端开发受限于它自身运行的的平台终端,这一点注定使移动端不像 PC 前端那样能够处理大量的复杂的业务场景。Model 数据大多来源于网络数据,拿到网络数据后客户端要做的事情就是将数据直接按照顺序画在界面上。随着业务的越来越来的深入,我们依赖的 service 服务可能在大多时间无法第一时间满足客户端需要的数据需求,移动端愈发的要自行处理一部分逻辑计算操作。这个时间一惯的做法是在控制器中处理,最终导致了控制器成了垃圾箱,越来越不可维护。
视图 view 通常是 UIKit 控件(component,这里根据习惯译为控件)或者编码定义的 UIKit 控件的集合。进入 .xib 或者 Storyboard 会发现一个 app、Button、Label 都是由这些可视化的和可交互的控件组成。View 不应该直接引用 Model,并且仅仅通过 IBAction 事件引用 controller。业务逻辑很明显不归入 view,视图本身没有任何业务。
2)过于轻的 Model:
早期的 Model 层,其实就是如果数据有几个属性,就定义几个属性,ARC 普及以后我们在 Model 层的实现文件中基本上看不到代码,基本上 .m 文件中的代码普遍是空。
同时与控制器的代码越来厚重形成强烈的反差,这一度让人不禁对现有的开发设计构思有所怀疑。
3)遗失的网络逻辑:
苹果使用的 MVC 的定义是这么说的:所有的对象都可以被归类为一个 Model,一个 view,或是一个控制器。就这些,那么把网络代码放哪里?和一个 API 通信的代码应该放在哪儿?
你可能试着把它放在 Model 对象里,但是也会很棘手,因为网络调用应该使用异步,这样如果一个网络请求比持有它的 Model 生命周期更长,事情将变的复杂。显然也不应该把网络代码放在 view 里,因此只剩下控制器了。这同样是个坏主意,因为这加剧了厚重控制器的问题。那么应该放在那里呢?显然 MVC 的 3 大组件根本没有适合放这些代码的地方。