iOS项目架构

一、架构分层
二、UI层架构
 1、MVC
  1.1 苹果版MVC
  1.2 变种MVC
 2、MVP
 3、MVVM


一、架构分层


架构分层是指把项目中所有的类划分到不同的层,目的是使项目逻辑更加清晰,提升开发和维护的效率。我一般会把项目分为三层:UI层、业务层和数据层。

  • UI层内部在调用业务层的API,UI层主要负责的是告诉业务层它想要什么数据(即想做什么业务)并传递一些必要的参数给业务层,然后等着业务层返回数据后直接拿着用就可以了;
  • 业务层内部在调用数据层的API,业务层主要负责的是决定数据的来源是从网络请求还是本地数据库,然后等着数据层给它返回rawData,把rawData处理成UI层能直接使用的Model、ModelArray等模型数据回调给UI层;
  • 数据层内部在调用网络请求(如AFN)或者本地数据库(如FMDB)的API,数据层主要负责是的加载rawData,然后把rawData回调给业务层。


二、UI层架构


1、MVC

1.1 苹果版MVC

MVC,即Model-View-Controller,它们的关系如下:

Controller的职责:

  • Controller负责持有View,创建View,并把View添加到窗口上显示;
  • Controller负责加载Model(当然这里UI层加载Model是通过告诉业务层加载的),加载完后就持有Model并显示在相应的View上;
  • Controller负责监听View与业务有关的事件,通过与Model的合作,来完成对应事件的业务。

View的职责:

  • View负责显示数据和效果,那怎么显示数据呢?View需要把供外界使用的子组件给暴露出去;
  • View负责响应与业务无关的事件,如某些事件会引发动画效果等,这应该尽量在View内部完成;
  • View负责响应与业务有关的事件并交给Controller去处理,怎么交给Controller呢?通过代理、block、通知等。

Model的职责:

  • Model只负责包装数据,不做任何其它操作。

苹果版MVC的优势就在于:

  • Model和View之间没有一点儿耦合,它们可以独立使用,具有高度复用性。

缺点也很明显:

  • Controller的代码过于臃肿,这主要体现在View的很多子组件暴露在外面,Model给View赋值的那个地方。
1.2 变种MVC

变种MVC是针对苹果版MVC的缺点进行的,变种的核心就在于:View持有了Model,把数据显示的逻辑放在了View内部来处理,而不再是通过View暴露子组件的方式来显示数据了。

变种MVC的优势就在于:

  • 在一定程度上为Controller瘦了身;
  • 将View内部的实现细节封装起来了,外界不需要知道View内部的实现细节,只需要给它一个Model就可以了。

缺点也很明显:

  • View明显耦合于Model,这个View无法再独立使用,必须绑定某个特定的Model一起使用。(不过我觉得这是可以接受的,毕竟我们既然选择了这种架构,就表明这种View专门就是用来绑定某个特定的Model显示的,而如果我们需要让一个View能显示各种Model,那可能就会选择苹果版MVC)

2、MVP

MVP,即Model-View-Presenter,它们的关系如下:

可见MVP和苹果版MVC几乎一模一样,它的Presenter就相当于苹果版MVC里Controller的角色,也就是说MVP就是把苹果版MVC Controller里的代码全都搬到Presenter里去做了,而ViewController里只需要管理好一堆的Presenter就行了。

可见在MVP里,Model和View也是互不侵扰的,而MVP给ViewController瘦身的手段就是所有的逻辑都搬到一个一个的Presenter里去了。

3、MVVM

MVVM,即Model-View-ViewModel,它们的关系如下:

可见MVVM和MVP如出一辙,MVP是用Presenter替代了苹果版MVC Controller的角色,而MVVM则是用ViewModel替代了苹果版MVC Controller的角色。

不过MVVM和MVP不同的地方就在于ViewModel和View存在一个双向绑定,具体地说就是:

  • ViewModel最基本的职责当然是起到Presenter的调度作用,因此它会持有(绑定)View;
  • 然后ViewModel之所以叫ViewModel,是因为它还是一个用来供View显示的实体,这个实体是拥有属性的,它的属性跟Model的属性基本保持一致,我们在加载到Model之后,会把Model的每个属性依次赋值给ViewModel相应的属性,而不是赋值给View去显示。而是View会持有(绑定)这个ViewModel,并监听ViewModel属性的变化来显示和更新UI,这就使得View更有封装性,同时显示数据和更新数据更加灵活。(View监听ViewModel属性的变化可以用RAC或者FaceBook的KVOController