谈谈MVVM和链式网络请求架构

前言

 

前一段时间一直在学习iOS的架构。为什么呢?

公司的架构一直是MVC,当我们正式上线的时候,项目已经有了超十万行代码。主要的VC一般都有2000行代码以上。

关键是,目前版本我们只做了三分之一的业务逻辑…

 

所以,架构重构吧。

 

正文

 

MVVM

 

MVVM: Model-View-ViewModel

 

MVVM其实是MVC的进化版,它将业务逻辑从VC中解耦到ViewModel,来实现VC大’瘦身’。

 

用代码解释吧!

 

做一个简单的登录判断:

 

创建LoginViewModel(逻辑处理),LoginModel(只放数据),LoginViewController。

这里不用LoginView是为了让初学者能更好的把精力集中在用ViewModel解耦上。

 

当然要是你这些都明白,你可以直接看Wzxhaha/RandomerFramework,这是我在做的独立项目Randomer的基本架构(SubClasses+Protocol+MVVM+RAC)以及它的登录注册模块。另外,感谢王隆帅的这篇文章为我打开了新世界的大门。

 

在LoginModel中加入方法

 

//.h

- (instancetype)initWithUserName:(NSString *)username password:(NSString *)password;

 

@property (nonatomic,copy,readonly)NSString * username;

@property (nonatomic,copy,readonly)NSString * password;

 

//.m

- (instancetype)initWithUserName:(NSString *)username password:(NSString *)password {

    if (self = [super init]) {

        _username = username;

        _password = password;

    }

    return self;

}

 

这个没什么好讲的,就是给Model加一个初始化方法。

 

在LoginViewModel中加入方法

 

#import "PersonModel.h"

 

- (instancetype)initWithPerson:(PersonModel *)person;

@property (nonatomic,assign,readonly)BOOL canLogin;

 

- (instancetype)initWithPerson:(PersonModel *)person {

    if (self = [super init]) {

     //在这做你绑定model后的处理

      _canLogin = [self valiCanLoginWithUserName:person.username password:person.password];

    }

    return self;

}

 

- (BOOL)valiCanLoginWithUserName:(NSString *)username password:(NSString *)password {

    if (username.length & password.length) {

        return YES;

    } else {

        return NO;

    }

}

 

给ViewModel添加个绑定Model的初始化方法,以及判断帐号密码是否有效的方法。

 

然后VC(或者View)就可以直接这样获得判断后的结果

 

PersonModel * person = [[PersonModel alloc]initWithUserName:@"10" password:@"10"];

PersonViewModel * viewModel = [[PersonViewModel alloc]initWithPerson:person];

 

NSLog(@"%d",viewModel.canLogin);

 

简单的功能的时候没什么,当你处理复杂的逻辑判断的时候,MVVM会有巨大优势。

 

顺便讲一下ReactiveCocoa,我之所以这么推崇MVVM,主要就是因为RAC和MVVM简直太配了!

 

ReactiveCocoa

 

RAC具有函数式编程和响应式编程的特性,要是对编程思想不熟的可以看我的WZXProgrammingIdeas

 

RAC最大的用处就是能监听到各个事件,RAC把这个叫做信号流,然后接受信号通过block回调,里面大量的使用了block,所以一定要用好@weakify(self)和@strongify(self)。

 

为什么说RAC和MVVM太配了?

 

MVVM是把方法解耦到ViewModel,但是还是要VC(V)调用的,那么判断什么时候调用的逻辑还是会复杂。

 

而RAC解决了这个问题,它负责监听事件,然后调用ViewModel来进行逻辑判断。

 

例如:

 

   [[_registerBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) {

        @strongify(self)

        [self.viewModel toRegisterWithType:Register];

    }];

 

    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) {

        @strongify(self)

        [self.viewModel loginWithUserName:self.usernameTextField.text password:self.usernameTextField.text Success:^(id response) {

        } failure:^{

            SHOW_ERROR(@"错误", @"账号或密码错误")

        } error:^(NSError *error) {

            SHOW_ERROR(@"错误", @"网络连接失败")

        }];

    }];

 

RAC监听了登录和注册按钮,使得代码简洁,而且结构十分紧凑。

 

Demo的话还是看这个吧Wzxhaha/RandomerFramework

https://github.com/Wzxhaha/RandomerFramework

 

或者简单版的WZXRACDemo

https://github.com/Wzxhaha/WZXRACDemo

 

链式网络请求框架

 

为什么封装WZXNetworking

 

这是一个容错性非常吓人的框架。

 

[[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001").RequestType(POST).HTTPHeader(nil).Parameters(nil).RequestSerialize(RequestSerializerHTTP).ResponseSerialize(ResponseSerializerJSON) startRequestWithSuccess:^(id response) {

 

        NSLog(@"success");

    } failure:^{

 

        NSLog(@"failure");

    }];

 

在这里除了.setRequest(url)和startRequestWithSuccess failure方法,其他都是非必要的。

 

你可以这样:

 

[[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001") startRequestWithSuccess:^(id response) {

 

        NSLog(@"success");

    } failure:^{

 

        NSLog(@"failure");

    }];

 

链式在参数和参数的选择很多的情况或者很有可能改动的情况下展现了惊人的优势。因为,它的改动十分方便,只不过添加或者修改一个方法。

 

打个比方:

 

换成集中式API封装应该是这样的:

 

- (void)GET:(NSString *)url

        parameters:(id)Parameters

        success:(SuccessBlock)success

        failure:(FailureBlock)failure;

 

当你要添加一个Version属性做API版本判断的时候,你能怎么办?只能重写方法,在方法中加入一个Version参数,然后所有使用的网络请求都要改变方法。

 

换成分布式API封装我们则不考虑对比了..

 

GeneralAPI *apiGeGet            = [[GeneralAPI alloc] initWithRequestMethod:@"get"];

apiGeGet.apiRequestMethodType      = RequestMethodTypeGET;

apiGeGet.apiRequestSerializerType  = RequestSerializerTypeHTTP;

apiGeGet.apiResponseSerializerType = ResponseSerializerTypeHTTP;

[apiGeGet setApiCompletionHandler:^(id responseObject, NSError * error) {

    NSLog(@"responseObject is %@", responseObject);

    if (error) {

        NSLog(@"Error is %@", error.localizedDescription);

    }

}];

[apiGeGet start];

 

这样的结构是否太松散?

 

再换成WZXNetworking

 

我们要做的只是再添加一个方法和一个成员变量,然后在原有方法后面加一个.method()

 

- (WZXNetworkManager * (^) (id some))method {

  return ^WZXNetworkManager (id some) {

     self.XXX = some

     return self;

  }

}

 

[[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001").method(some) startRequestWithSuccess:^(id response) {

 

        NSLog(@"success");

    } failure:^{

 

        NSLog(@"failure");

    }];

 

代码放这:WZXNetworking

https://github.com/Wzxhaha/WZXNetworking

 

至于链式是怎么实现的,还是看那个WZXProgrammingIdeas

https://github.com/Wzxhaha/WZXProgrammingIdeas

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MVVM和MVC都是一种设计思想,但是它们在实现上有一些区别。其中,MVVM主要解决了MVC中大量DOM操作导致页面渲染性能降低、加载速度变慢的问题。最大的区别在于MVVM实现了View和Model的自动同步,也就是说当Model的属性改变时,不需要手动操作DOM元素来改变View的显示,而是会自动变化。 另外,MVVM还可以通过使用同一个Model调用不同的View(比如柱状图、表格)来得到不同的页面展示形式,这样可以减少Model的代码量,并且更易于维护Model和View之间的关系。 所以,从功能和实现角度来看,MVVM比MVC更加方便和高效。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [对MVVM的理解 MVVM和MVC的区别](https://blog.csdn.net/weixin_45695200/article/details/120211592)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [MVC和MVVM有什么区别](https://blog.csdn.net/weixin_70443954/article/details/128082351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值