谈谈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中加入方法

 
 
  1. //.h 
  2.  
  3. - (instancetype)initWithUserName:(NSString *)username password:(NSString *)password
  4.  
  5.   
  6.  
  7. @property (nonatomic,copy,readonly)NSString * username; 
  8.  
  9. @property (nonatomic,copy,readonly)NSString * password
  10.  
  11.  
  12. //.m 
  13.  
  14. - (instancetype)initWithUserName:(NSString *)username password:(NSString *)password { 
  15.  
  16.     if (self = [super init]) { 
  17.  
  18.         _username = username; 
  19.  
  20.         _password = password
  21.  
  22.     } 
  23.  
  24.     return self; 
  25.  
  26.  

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

在LoginViewModel中加入方法

 
 
  1. #import "PersonModel.h" 
  2.  
  3.   
  4.  
  5. - (instancetype)initWithPerson:(PersonModel *)person; 
  6.  
  7. @property (nonatomic,assign,readonly)BOOL canLogin; 
  8.  
  9.  
  10. - (instancetype)initWithPerson:(PersonModel *)person { 
  11.  
  12.     if (self = [super init]) { 
  13.  
  14.      //在这做你绑定model后的处理 
  15.  
  16.       _canLogin = [self valiCanLoginWithUserName:person.username password:person.password]; 
  17.  
  18.     } 
  19.  
  20.     return self; 
  21.  
  22.  
  23.   
  24.  
  25. - (BOOL)valiCanLoginWithUserName:(NSString *)username password:(NSString *)password { 
  26.  
  27.     if (username.length & password.length) { 
  28.  
  29.         return YES; 
  30.  
  31.     } else { 
  32.  
  33.         return NO
  34.  
  35.     } 
  36.  
  37.  

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

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

 
 
  1. PersonModel * person = [[PersonModel alloc]initWithUserName:@"10" password:@"10"]; 
  2.  
  3. PersonViewModel * viewModel = [[PersonViewModel alloc]initWithPerson:person]; 
  4.  
  5.   
  6.  
  7. 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来进行逻辑判断。

例如:

 
 
  1. [[_registerBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) { 
  2.  
  3.       @strongify(self) 
  4.  
  5.       [self.viewModel toRegisterWithType:Register]; 
  6.  
  7.   }]; 
  8.  
  9.  
  10.  
  11.   [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) { 
  12.  
  13.       @strongify(self) 
  14.  
  15.       [self.viewModel loginWithUserName:self.usernameTextField.text password:self.usernameTextField.text Success:^(idresponse) { 
  16.  
  17.       } failure:^{ 
  18.  
  19.           SHOW_ERROR(@"错误", @"账号或密码错误"
  20.  
  21.       } error:^(NSError *error) { 
  22.  
  23.           SHOW_ERROR(@"错误", @"网络连接失败"
  24.  
  25.       }]; 
  26.  
  27.   }];  

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

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

https://github.com/Wzxhaha/RandomerFramework

或者简单版的WZXRACDemo

https://github.com/Wzxhaha/WZXRACDemo

链式网络请求框架

为什么封装WZXNetworking

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

 
 
  1. [[WZXNetworkManagermanager].setRequest(@"http://192.168.1.40:8001").RequestType(POST).HTTPHeader(nil).Parameters(nil).RequestSerialize(RequestSerializerHTTP).ResponseSerialize(ResponseSerializerJSON) startRequestWithSuccess:^(id response) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }]; 

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

你可以这样:

 
 
  1. [[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001") startRequestWithSuccess:^(id response) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }];  

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

打个比方:

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

 
 
  1. - (void)GET:(NSString *)url 
  2.  
  3.         parameters:(id)Parameters 
  4.  
  5.         success:(SuccessBlock)success 
  6.  
  7.         failure:(FailureBlock)failure; 

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

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

 
 
  1. GeneralAPI *apiGeGet            = [[GeneralAPI alloc] initWithRequestMethod:@"get"]; 
  2.  
  3. apiGeGet.apiRequestMethodType      = RequestMethodTypeGET; 
  4.  
  5. apiGeGet.apiRequestSerializerType  = RequestSerializerTypeHTTP; 
  6.  
  7. apiGeGet.apiResponseSerializerType = ResponseSerializerTypeHTTP; 
  8.  
  9. [apiGeGet setApiCompletionHandler:^(id responseObject, NSError * error) { 
  10.  
  11.     NSLog(@"responseObject is %@", responseObject); 
  12.  
  13.     if (error) { 
  14.  
  15.         NSLog(@"Error is %@", error.localizedDescription); 
  16.  
  17.     } 
  18.  
  19. }]; 
  20.  
  21. [apiGeGet start];  

这样的结构是否太松散?

再换成WZXNetworking

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

 
 
  1. - (WZXNetworkManager * (^) (id some))method { 
  2.  
  3.   return ^WZXNetworkManager (id some) { 
  4.  
  5.      self.XXX = some 
  6.  
  7.      return self; 
  8.  
  9.   } 
  10.  
  11.  
 
 
  1. [[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001").method(some) startRequestWithSuccess:^(idresponse) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }];  







本文作者:佚名
来源:51CTO
目录
相关文章
|
6天前
|
设计模式 存储 前端开发
MVVM、MVC、MVP三种常见软件架构设计模式的区别
MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。
27 12
|
22天前
|
前端开发
什么是MVVM架构?
MVVM是Model-View-ViewModel的简写。它本质上就是MVC的改进版。MVVM模式有助于将应用程序的业务和表示逻辑与用户界面 (UI) 清晰分离。 保持应用程序逻辑和UI之间的清晰分离有助于解决许多开发问题,并使应用程序更易于测试、维护和演变。 它还可以显著提高代码重用机会,并允许开发人员和UI设计人员在开发应用各自的部分时更轻松地进行协作。
25 2
|
8天前
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
|
13天前
|
运维 安全 网络架构
【计算巢】网络模拟工具:设计与测试网络架构的有效方法
【6月更文挑战第1天】成为网络世界的超级英雄,利用网络模拟工具解决复杂架构难题!此工具提供安全的虚拟环境,允许自由设计和测试网络拓扑,进行性能挑战和压力测试。简单示例代码展示了创建网络拓扑的便捷性,它是网络设计和故障排查的“魔法棒”。无论新手还是专家,都能借助它探索网络的无限可能,开启精彩冒险!快行动起来,你会发现网络世界前所未有的乐趣!
【计算巢】网络模拟工具:设计与测试网络架构的有效方法
|
14天前
|
安全 网络安全 API
构建高效微服务架构的五大关键策略网络安全与信息安全:防范网络威胁的关键策略
【5月更文挑战第31天】 在现代软件开发领域,微服务架构已经成为实现灵活、可扩展及容错系统的重要解决方案。本文将深入探讨构建高效微服务架构的五个核心策略:服务划分原则、API网关设计、服务发现与注册、熔断机制以及持续集成与部署。这些策略不仅有助于开发团队提升系统的可维护性和可伸缩性,同时也确保了高可用性和服务质量。通过实践案例和性能分析,我们将展示如何有效应用这些策略以提高微服务的性能和稳定性。
|
22天前
|
前端开发 中间件 程序员
app的组件化之路:业务组件化与中间件,MVVM架构的作用
app的组件化之路:业务组件化与中间件,MVVM架构的作用
21 0
|
28天前
|
前端开发 Android开发
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
|
28天前
|
安全 网络协议 网络安全
网络安全笔记整理,你花了多久弄明白架构设计
网络安全笔记整理,你花了多久弄明白架构设计
|
30天前
|
前端开发
MVVM LiveData+DataBinding+Lifecycle+ViewModel架构
MVVM LiveData+DataBinding+Lifecycle+ViewModel架构
22 1
|
30天前
|
机器学习/深度学习 安全 网络安全
数字堡垒的构筑者:网络安全与信息安全的深层剖析构建高效微服务架构:后端开发的新趋势
【4月更文挑战第30天】在信息技术高速发展的今天,构建坚不可摧的数字堡垒已成为个人、企业乃至国家安全的重要组成部分。本文深入探讨网络安全漏洞的本质、加密技术的进展以及提升安全意识的必要性,旨在为读者提供全面的网络安全与信息安全知识框架。通过对网络攻防技术的解析和案例研究,我们揭示了防御策略的关键点,并强调了持续教育在塑造安全文化中的作用。

热门文章

最新文章