All Projects → MrLujh → MVVM

MrLujh / MVVM

Licence: MIT license
MVVM 开发模式

Programming Languages

objective c
16641 projects - #2 most used programming language

MVVM 开发模式

浅谈MVVM

  • 项目开发中,用的比较多的就是MVC,高级一点的就会用MVVM,因为后者开发比较灵活,界面便于维护。另外一种MVP,开发中的比较少,主流的就是MVC,MVVM。个人比较偏爱MVVM,在项目中用的比较多。

概述 引用自iOS应用架构谈

  • MVVM的出现主要是为了解决在开发过程中Controller越来越庞大的问题,变得难以维护,所以MVVM把数据加工的任务从Controller中解放了出来,使得Controller只需要专注于数据调配的工作,ViewModel则去负责数据加工并通过通知机制让View响应ViewModel的改变。

  • MVVM是基于胖Model的架构思路建立的,然后在胖Model中拆出两部分:Model和ViewModel。ViewModel本质上算是Model层(因为是胖Model里面分出来的一部分),所以View并不适合直接持有ViewModel,因为ViewModel有可能并不是只服务于特定的一个View,使用更加松散的绑定关系能够降低ViewModel和View之间的耦合度。

  • 还有一个让人很容易忽略的问题,大部分国内外资料阐述MVVM的时候都是这样排布的:

View<->ViewModel <->Model
  • 造成了MVVM不需要Controller的错觉,现在似乎发展成业界开始出现MVVM是不需要Controller的声音了。其实MVVM是一定需要Controller的参与的,虽然MVVM在一定程度上弱化了Controller的存在感,并且给Controller做了减负瘦身(这也是MVVM的主要目的)。但是,这并不代表MVVM中不需要Controller,MMVC和MVVM他们之间的关系应该是这样:
View <-> C <-> ViewModel <->Model
  • 所以使用MVVM之后,就不需要Controller的说法是不正确的。严格来说MVVM其实是MVCVM。从中可以得知,Controller夹在View和ViewModel之间做的其中一个主要事情就是将View和ViewModel进行绑定。在逻辑上,Controller知道应当展示哪个View,Controller也知道应当使用哪个ViewModel,然而View和ViewModel它们之间是互相不知道的,所以Controller就负责控制他们的绑定关系,所以叫Controller/控制器就是这个原因。

  • 前面扯了那么多,其实归根结底就是一句话:在MVC的基础上,把C拆出一个ViewModel专门负责数据处理的事情,就是MVVM。然后,为了让View和ViewModel之间能够有比较松散的绑定关系,于是我们使用ReactiveCocoa,KVO,Notification,block,delegate和target-action都可以用来做数据通信,从而来实现绑定,但都不如ReactiveCocoa提供的RACSignal来的优雅,如果不用ReactiveCocoa,绑定关系可能就做不到那么松散那么好,但并不影响它还是MVVM。

  • MVVM(View-ViewManger-C-ViewModel-Model) image

  • 这种设计的目的是保持View和Model的高度纯洁,提高可扩展性和复用度。在日常开发中,ViewModel是为了拆分Controller业务逻辑而存在的,所以ViewModel需要提供公共的服务接口,以便为Controller提供数据。而ViewManger的作用相当于一个小管家,帮助Controller来分别管理每个subView,ViewManger负责接管来自View的事件,也负责接收来自Controller的模型数据,而View进行自己所负责的视图数据绑定工作。Controller则是最后的大家长,负责将ViewModel和ViewManger进行绑定,进行数据转发工作。把合适的数据模型分发给合适的视图管理者。

  • 日常开发中,往往一个视图页面交由一个控制器进行管理,而一个页面上又有N个小的子页面,这就要求我们来对这些视图进行合适的分层处理,拆分视图,将这些视图进行封装,将复杂View抽象成独立的类,不必暴露出具体的实现细节。这样做的好处是,简化应用层的层级复杂度,同时也方便进行管理,视图结构就会变得很清晰。

  • 这样的架构设计,就像一条生产线,ViewModel进行数据的采集和加工,Controller则进行数据的装配和转发工作从而进行负责View的展示工作和管理View的事件。这样,不管哪个环节,都是可以更换的,同时也提高了复用性。

项目代码结构

image

架构讲解

image

  • viewMode层 根据返回的数据 提前计算好所有控件的frame  在model的基础上封装了一个viewMode层 image

  • 数据处理

// 模型转换视图模型 MvvmModel -> MvvmModelF
           
            for (MvvmModel *mvvmModel in arr) {
                
                MvvmModelF *modelF = [[MvvmModelF alloc] init];
                
                modelF.model = [MvvmModel mj_objectWithKeyValues:mvvmModel];
                
                [self.data addObject:modelF];
            }
  • cell层数据传递
/*
 问题:
 1.cell的高度应该提前计算出来
 2.cell的高度必须要先计算出每个子控件的frame,才能确定
 3.如果在cell的setStatus方法计算子控件的位置,会比较耗性能
 
 解决:MVVM思想
 M:模型
 V:视图
 VM:视图模型(模型包装视图模型,模型+模型对应视图的frame)
 */
- (void)setModelF:(MvvmModelF *)modelF
{
    _modelF = modelF;
   
    //设置卡frame
    self.cellBackView.frame = modelF.cellBackViewFrame;
    self.cellBackView.modelF = modelF;
} 

推荐

应用架构文章

部分来自原创微信公众平台-移动开发前线

MVVM学习文章

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].