欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS MVVM架构总结

程序员文章站 2022-03-24 12:28:54
为什么使用MVVM iOS中,我们使用的大部分都是MVC架构。虽然MVC的层次明确,但是由于功能日益的增加、代码的维护,使得更多的代码被写在了Controller中,这样Controller就显得非常臃肿。为了给Controller瘦身,后来又从MVC衍生出了一种新的架构模式MVVM架构。 MVVM ......

 

为什么使用mvvm

ios中,我们使用的大部分都是mvc架构。虽然mvc的层次明确,但是由于功能日益的增加、代码的维护,使得更多的代码被写在了controller中,这样controller就显得非常臃肿。
为了给controller瘦身,后来又从mvc衍生出了一种新的架构模式mvvm架构。

mvvm分别指什么

mvvm就是在mvc的基础上分离出业务处理的逻辑到viewmodel层,即:

model层:请求的原始数据
view层:视图展示,由viewcontroller来控制
viewmodel层:负责业务处理和数据转化

简单来说,就是api请求完数据,解析成model,之后在viewmodel中转化成能够直接被视图层使用的数据,交付给前端(view层)。

mvvm与mvc的不同

首先我们简化一下mvc的架构模式图:

 iOS MVVM架构总结

 

iOS MVVM架构总结
 

在这里,controller需要做太多得事情,表示逻辑、业务逻辑,所以代码量非常的大。而mvvm:

 iOS MVVM架构总结

 

iOS MVVM架构总结
 

 

mvvm的实现

比如我们有一个需求:一个页面,需要判断用户是否手动设置了用户名。如果设置了,正常显示用户名;如果没有设置,则显示“博客园0122”这种格式。(虽然这些本应是服务器端判断的)
我们看看mvc和mvvm两种架构都是怎么实现这个需求的

mvc:

model类:

#import <foundation/foundation.h>

@interface user : nsobject

@property (nonatomic, copy) nsstring *username;
@property (nonatomic, assign) nsinteger userid;

- (instancetype)initwithusername:(nsstring *)username userid:(nsinteger)userid;

@end
@implementation user

- (instancetype)initwithusername:(nsstring *)username userid:(nsinteger)userid {
    self = [super init];
    if (!self) return nil;
    _username = username;
    _userid   = userid;
    return self;
}

@end

 

viewcontroller类:

#import "homeviewcontroller.h"
#import "user.h"

@interface homeviewcontroller ()

@property (nonatomic, strong) uilabel *lb_username;
@property (nonatomic, strong) user *user;

@end
@implementation homeviewcontroller

- (void)viewdidload {
    [super viewdidload];

    //创建user实例并初始化
    if (_user.username.length > 0) {
        _lb_username.text = _user.username;
    } else {
        _lb_username.text = [nsstring stringwithformat:@"博客园%ld", _user.userid];
    }
}

@end

 

这里我们需要将表示逻辑也放在viewcontroller中。

mvvm:

model类:

#import <foundation/foundation.h>

@interface user : nsobject

@property (nonatomic, copy) nsstring *username;
@property (nonatomic, assign) nsinteger userid;

@end

 

viewmodel类:

声明:

#import <foundation/foundation.h>
#import "user.h"

@interface userviewmodel : nsobject

@property (nonatomic, strong) user *user;
@property (nonatomic, copy) nsstring *username;

- (instancetype)initwithusername:(nsstring *)username userid:(nsinteger)userid;

@end

 

实现:

#import "userviewmodel.h"

@implementation userviewmodel

- (instancetype)initwithusername:(nsstring *)username userid:(nsinteger)userid {
    self = [super init];
    if (!self) return nil;
    _user = [[user alloc] initwithusername:username userid:userid];
    if (_user.username.length > 0) {
        _username = _user.username;
    } else {
        _username = [nsstring stringwithformat:@"博客园%ld", _user.userid];
    }
    return self;
}

@end

 

controller类:

#import "homeviewcontroller.h"
#import "userviewmodel.h"

@interface homeviewcontroller ()

@property (nonatomic, strong) uilabel *lb_username;
@property (nonatomic, strong) userviewmodel *userviewmodel;

@end
@implementation homeviewcontroller

- (void)viewdidload {
    [super viewdidload];

    _userviewmodel = [[userviewmodel alloc] initwithusername:@"liu" userid:123456];
    _lb_username.text = _userviewmodel.username;
}

@end

 

可见,controller中我们不需要再做多余的判断,那些表示逻辑我们已经移植到了viewmodel中,viewcontroller明显轻量了很多。说白了,就是把原来viewcontroller层的业务逻辑和页面逻辑等剥离出来放到viewmodel层。

总结:

  • mvvm同mvc一样,目的都是分离model与view,但是它更好的将表示逻辑分离出来,减轻了controller的负担;
  • viewcontroller中不要引入model,引入了就难免会在controller中对model做处理;
  • 对于很简单的界面使用mvvm会增加代码量,但如果界面中内容很多、cell样式也很多的情况下使用mvvm可以很好地将vc中处理cell相关的工作分离出来。

写到这里,mvvm基本上就算结束了。重要的还是去实践,在实践中检验真理。




https://www.jianshu.com/p/f1d0f7f01130