iOS进阶之架构设计MVC(1)iOS进阶之架构设计MVP(2)
前言:
前两篇文章已经理解MVC、MVP的设计模式。特别是MVP,比较难以理解,不好把握。需要多多实践,对比、来优化P段,找到最适合自己的写法。有了MVP的理解之后,就像走过来一段嘿嘿的山洞,一下豁然开朗。见到了世外桃源。MVVM的设计模式是结构比较清晰的。我们来看一下。
MVP对比MVVM
其实看了MVP,又看看MVVM,对比下感觉没什么区别。不就是P换成了VM吗?
其实还是有区别的,P通过协议和View通信。VM则可以通过双向绑定的方式和View进行双向影响。这样更隔离。耦合更低。
一、MVVM组成
MVVM由3部分组成:Model 、 View 、ViewModel。
- M:Model: 作为数据的容器。
- V:View、部分ViewController组成。负责界面的展示以及用户交互的处理。
- VM:ViewModel: 负责业务逻辑处理。就是把原来ViewController层的业务逻辑和页面逻辑等剥离出来放到ViewModel层
二、基本要点
- View持有ViewModel:在View中通过绑定的方式关联UI元素和ViewModel的属性,UI元素的属性变化和ViewMode的数据属性进行双向影响。
- ViewModel持有Model:Model为ViewModel提供数据支持,同时ViewModel的数据属性变化也会影响Model上,用于数据提交等。
Model和ViewModel的功能区别在于,ViewModel是View提供数据支持的,其结构和View保持一致。Model来源于业务处理,保持业务数据的基本关联和完整性。 - 当Model层结束查询或者运算时将结果更新到ViewModel层,ViewModel层因为存在和View的绑定,使得UI层得到通知更新,体现了数据驱动界面的思想。
最基本的规则:
1.View持有ViewModel 反之不持有
2.ViewModel持有Model 反之不持有
真正的mvvm应该是viewModel与View上的数据是双向绑定的,这里只是简单实现结构的分层,并没有实现双向绑定,双向绑定内容后期加上会再分享出来。
demo示例:ios MVVM实践 刷新网络请求+tableView展示数据。 demo
类方法属性规范
- Person model
@interface Person : NSObject
- (instancetype)initwithSalutation:(NSString *)salutation firstName:(NSString *)firstName lastName:(NSString *)lastName birthdate:(NSDate *)birthdate;
@property (nonatomic, readonly) NSString *salutation;
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
@property (nonatomic, readonly) NSDate *birthdate;
@end
- PersonViewModel.h
@interface PersonViewModel : NSObject
- (instancetype)initWithPerson:(Person *)person;
@property (nonatomic, readonly) Person *person;
@property (nonatomic, readonly) NSString *nameText;
@property (nonatomic, readonly) NSString *birthdateText;
@end
- PersonViewModel.m
@implementation PersonViewModel
- (instancetype)initWithPerson:(Person *)person {
self = [super init];
if (!self) return nil;
_person = person;
if (person.salutation.length > 0) {
_nameText = [NSString stringWithFormat:@"%@ %@ %@", self.person.salutation, self.person.firstName, self.person.lastName];
} else {
_nameText = [NSString stringWithFormat:@"%@ %@", self.person.firstName, self.person.lastName];
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE MMMM d, yyyy"];
_birthdateText = [dateFormatter stringFromDate:person.birthdate];
return self;
}
@end
- viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.nameLabel.text = self.viewModel.nameText;
self.birthdateLabel.text = self.viewModel.birthdateText;
}
MVVM 的优势
低耦合:View 可以独立于Model变化和修改,一个 viewModel 可以绑定到不同的 View 上
可重用性:可以把一些视图逻辑放在一个 viewModel里面,让很多 view 重用这段视图逻辑
独立开发:开发人员可以专注于业务逻辑和数据的开发 viewModel,设计人员可以专注于页面设计
可测试:通常界面是比较难于测试的,而 MVVM 模式可以针对 viewModel来进行测试
MVVM中View和Model的双向绑定
绑定关系的建立可以依赖第三方库,如ReactiveCoca相关的库实现绑定
自己实现View和Model的绑定。ViewModel中可以设置Delegate,block,KVO等,用来完成model到view的绑定;另外View中也可以通过ViewModel把View的改变通知到model。