iOS架构设计之MVVM详细教程

前言

MVVM比MVC要强很多,其最大的作用就是给Controller瘦身,逻辑更清晰。如果你还在使用MVC的模式,建议你开始用MVVM。

当然有很多朋友都结合MVVM使用了RAC,我也用过一段时间,但最终还是放弃了。至于原因是个人习惯问题。

问题

很多人也在思考为Controller瘦身:

比如有些人把所有的逻辑,多写进了M,这是的M可能有一堆属性比如name,sex,age,还会有一个包含自己的数据,网络请求等等等,看起来会很乱。

比如还有些人会选择继承,把很多列表这种相似的网络请求写到父类里。

比如更有些人会选择用分类来进行数据的处理。

总之,像继承,分类,Model等等等,他们都有自己的职责,为Controller瘦身的正确姿势:

我依然建议大家使用MVVM ! 即使你的项目并不复杂 !

MVVM

我们以一个Person的模块(列表展示数据,详情可以编辑数据。)举例子,详细说明下如何设计一个MVVM的架构。

项目结构图:

架构设计:

  • Model数据模型

    这里的数据模型和传统MVC的M应该是一直的,其主要的作用是数据的映射。用的比较多的是通过YYModle把JsonObj,Dic之类转为对象。

    比如我们创建了一个Person类:

     
      #import < Foundation/Foundation.h > 
      @interface Person : NSObject
      //id
      @property (nonatomic,copy) NSString *pId;
      //姓名
      @property (nonatomic,copy) NSString *name;
      @end
     复制代码

    写到这里就差不多了,M层只关心数据的结构。

  • ViewModel

    ViewModel相对比较复杂,做的事比较多,也比较杂。

    • 网络请求

    • 数据缓存读写

    • 验证器 (表单传参,返回值等)

    • 数据处理

  • View试图层

    视图层只会关心2件事,1是如何构建界面,2是展示什么数据(不关数据的处理过程),所以通常会有一个Model的属性。

    View一般分为这几类:

    • Cell (包括Table的和Collection)
    • View (纯代码较多)
    • Storyboard (简单的界面,V都在这里了)

    记得刚接触iOS开发我习惯用纯代码,后来是XIB,在后来由于iPhone尺寸也开始出现了多样化,于是乎我也过度到了Storyboard。

    当然没有那种是最好的方案,很多是个人习惯问题,但我更习惯用SB外加一些纯代码的混合模式吧。至于XIB我放弃了。

    当用SB时会有两种情况:

    • 简单的TableView:

    我们只需要把Cell单独创建一下就好:

    PersonCell.h  
    复制代码

    PersonCell.m

    我习惯把控件写在.m里面,在.h暴露一个Model来接收该显示的值。

    这样写的另一个好处就是同样为Controller瘦身,应为在创建Cell后,你只需要一个类似这样的代码,即可完成数据的展示。

    cell.personM = [self.personVM.persons objectAtIndex:indexPath.row]


    • 复杂的View

      View并没有TableView那么的友好,有的复杂界面,N多个控件,除了SB的设置外,还要自己去写Layer之类的样式。

      比如我们Demo中的(Demo简单,实际情况复杂),查看编辑人物信息:

      用SB你会发现,所有的控件都会关联到Controller里,有些事件(Action)的确很方便,但你要对一些View控件设置样式时,违背了我们为Controll瘦身的初衷。

      所以我更喜欢创建一个独立的View,承载视图层。

      即PersonDetailView:

      PersonDetailView.h

      在.h中,我们依然只曝露一个Model用来接收显示的数据

      PersonDetailView.m

      在.m中我们的思路是一样的,可以在View初始化时修改样式,利用setter方法赋值,以及一些控件的delegate,Action处理

      那么如果我的v层有个button的action,如何传递给Controller, 我通常习惯用delegate,block完成事件的传递。


  • Controller 控制器

    写了这么多终于要写C了,既然为C瘦身,那么到底C瘦了多少呢?

    我们先看下列表的代码:

    .h没什么东西,我就不写了,下面是PersonListController.m

    一共大概50左右,感觉还是可以的。而且代码的可读性极强。

    通常实际情况要比这种简单的列表还要负责的多,比如下拉刷新,加载更多,界面统计,导航样式等等,类似情况我更倾向用继承的方式进行代码瘦身。

    注意:

    在PersonDetailViewController,我把整个的PersonViewModel传了过去,而不是只传了一个选中的Person。

    Why?

    就像我刚才说的,PersonViewModel里包含了整个模块大部分的网络请求,以及验证器,在PersonDetailViewController修改人物信息中会用到。

    PersonDetailViewController.h

    PersonDetailViewController.m

    很显然,详情要做的几件事:

    1. 显示一下当前的头像和名称 (列表传值VM来的)
    2. 实现V的代理 (修改的头像点击事件,得到修改的名称)
    3. 完成网络请求
    4. 修改完成后,返回列表,通知列表从新加载数据 (Demo忽略了)

    通过这样的架构,我们可以看到,略微复杂一些的DetailViewController的结构也是非常清晰的,而且代码量不多,可读性极强。


总结

本文只是抛砖引玉,大致讲了一些最基本的MVVM框架,要想写出好的代码架构,还需要更多的分层。

在处理非常复杂的业务时,VM已经不能满足我们的业务需要,

这时我们可能需要一个Service层来处理。

又比如网络请求时,我们要封装一个网络层。

总之,还是希望大家根据不同的项目特点,做好因地制宜。


注:

后面我会单独写关于网络请求,数据库FMDB封装等,希望我的文章可以帮助到你

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值