快捷搜索:

架构模式

2019-10-11 作者:2019精准正版资料   |   浏览(107)

正版香港马报免费资料 1image

以上三者的交互关系。什么关系?

  1. Model 不与 View直接通话,如图中Model和View之间的两黄实线。
  2. Model 与 Controller 通话,如图中Model和Controller中两灰色虚实线、当中的绿色箭头、Model上橙色的KVO。
  3. 正版香港马报免费资料,View与 controller 通话,如图中Controller和View之间两灰色虚实线、当中的Outlet绿色箭头、黄色的delegate和data source。
  4. View上action 与 controller 上的target。
  5. Model上KVO发送端与controller上的黄色接受端。

目前App 中最常用的code习惯如下图

正版香港马报免费资料 2image

通过这张图可以发现, 用户信息页面作为业务场景Scene需要展示多种数据M(Blog/Draft/UserInfo), 所以对应的有多个View(blogTableView/draftTableView/image…), 但是, 每个MV之间并没有一个连接层C, 本来应该分散到各个C层处理的逻辑全部被打包丢到了Scene这一个地方处理, 也就是M-C-V变成了MM…-Scene-…VV, C层就这样莫名其妙的消失了.

另外, 作为V的两个cell直接耦合了M(blog/draft), 这意味着这两个V的输入被绑死到了相应的M上, 复用无从谈起.

那么正确的MVC是什么呢?如下图

正版香港马报免费资料 3image

1、胖model的产生2、Massive View Controller的产生3、过度隔离V&M4、产生太多轻量级的model5、遗失网络逻辑6、较差的可测试性7、业务逻辑与视图逻辑强耦合

相关参考连接

正版香港马报免费资料 4image

Model View Presenter

正版香港马报免费资料 55.png

Controller中的所有逻辑都放在Presenter中实现,与MVC不同的是Model与View是没有任何联系的,都是通过Presenter来交互

Presenter持有MVPView与MVPModel

#import "MVPViewController.h"#import "Presenter.h"#import "MVPModel.h"#import "MVPView.h"@interface MVPViewController () @property (nonatomic, strong) Presenter *presenter;@property (nonatomic, strong) MVPView *mvpView;@property (nonatomic, strong) MVPModel *mvpModel;@end@implementation MVPViewController- viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. _presenter = [[Presenter alloc] init]; _mvpView = [[MVPView alloc] init]; _mvpView.frame = self.view.bounds; [self.view addSubview:_mvpView]; _mvpModel = [MVPModel new]; _mvpModel.content = @"MVP的模式"; // model还没赋值 _presenter.model = _mvpModel; _presenter.view = _mvpView; [_presenter usageLogic];}@end

MVVM其实是MVC的升级版,controller & view 直接通过viewModel 读取数据然后展示在界面上

正版香港马报免费资料 67.png

MVVM 简单一点说 : 双向绑定(通过viewModel 绑定view 与 model)

1、View 引用了viewModel ,但是反过来不行2、viewModel引用了model,但是反过来不行3、MVVM模式依赖于数据绑定,它是一个框架级别的特性,用于自动连接对象属性和UI控件。

1、Block2、使用reactiveCocoa库

这个库包含了函数式编程和响应式编程。其实reactiveCocoa库就是MVVM模式的核心。不使用 RAC :ViewModel处理完数据需要刷新 View等操作都是通过 Block回调来实现,不免是有些麻烦的。使用 RAC :在 View初始化的时候就和 ViewModel进行绑定,只要 ViewModel的数据有所变化,便自动更新 View。RAC 缺点:数据绑定使得一个位置的 Bug被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了

reactiveCocoa 俗称RAC,属于函数式响应编程,极大的简化了逻辑,方便使用

1、替换代理方法2、替换KVO3、替换NSNotification4、替换UIControl 的一些响应事件5、替换NSTimer等等,采用管道式通信机制,使逻辑更易理解

ReactiveCocoa入门教程:第一部分ReactiveCocoa入门教程: 第二部分ReactiveCocoa源码解析ReactiveCocoa常用方法MVVM+RAC 从框架到实战

使用RAC模拟请求客户档案与仓库档案

1.先请求客户档案数量,再根据数量分批次请求客户档案数据

2.先请求仓库档案数量,再根据数量分批次请求仓库档案数据

- viewDidLoad RACSignal *consumerSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //模拟发送一次获取客户更新数量的请求 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //假如获取到count 5 [self requestConsumerDataWith:subscriber]; }); return nil; }]; [consumerSignal subscribeNext:^(id _Nullable x) {g NSLog(@"客户档案更新结束%@",x); }]; RACSignal *warehouseSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //模拟发送一次获取仓库更新数量的请求 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //假如获取到count 5 [self requestConsumerDataWith:subscriber]; }); return nil; }]; [warehouseSignal subscribeNext:^(id _Nullable x) { NSLog(@"仓库档案更新结束%@",x); }]; //连接两个信号,只有两个信号都触发时,才能刷新UI 或者让HUD 消失 [self rac_liftSelector:@selector(updateUIWithR1:r3:) withSignalsFromArray:@[warehouseSignal,consumerSignal]]; }- requestConsumerDataWith:(id<RACSubscriber>)subScriber_consumer{ RACSignal *consumerSignal = nil; for (int i = 1; i < 5; i++) { RACSignal *single_temp = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [subscriber sendNext:@; return nil; }]delay:i]; if (!consumerSignal) { consumerSignal = single_temp; }else{ consumerSignal = [consumerSignal combineLatestWith:single_temp]; } } [consumerSignal subscribeNext:^(id _Nullable x) { [subScriber_consumer sendNext:@"客户档案请求成功!!!"]; }];}- requestWarehouseDataWith:(id<RACSubscriber>)subScriber_warehouse{ RACSignal *consumerSignal = nil; for (int i = 1; i < 5; i++) { RACSignal *single_temp = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [subscriber sendNext:@; return nil; }]delay:i]; if (!consumerSignal) { consumerSignal = single_temp; }else{ consumerSignal = [consumerSignal combineLatestWith:single_temp]; } } [consumerSignal subscribeNext:^(id _Nullable x) { [subScriber_warehouse sendNext:@"仓库档案请求成功!!!"]; }];}// 更新UI- updateUIWithR1:data r3:data2{ 

本文由正版香港马报免费资料发布于2019精准正版资料,转载请注明出处:架构模式

关键词:

  • 上一篇:没有了
  • 下一篇:没有了