MVVM模式是什么
根据唐巧的文章和Objective-C.io介绍,MVVM是最早于2005年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出,并且应用在微软的软件开发中.当时 MVC 已经被提出了 20 多年了,可见两者出现的年代差别有多大.
下面祭出一张微软大神的手绘图
MVVM的目的是什么
在上一篇中MFC模式中提出的问题是,ViewController层过于臃肿,Objective-C.io中提出,使用MVVM可以很好的解决这个问题.
MVVM的示例
由于我本身并不经常使用MVVM的设计模式,所以并没有很有心得的代码,我们以Objective-C.io中的代码举例
首先定义一个Person
@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
MVC中使用一个VC展示它
- (void)viewDidLoad {
[super viewDidLoad];
if (self.model.salutation.length > 0) {
self.nameLabel.text = [NSString stringWithFormat:@"%@ %@ %@", self.model.salutation, self.model.firstName, self.model.lastName];
} else {
self.nameLabel.text = [NSString stringWithFormat:@"%@ %@", self.model.firstName, self.model.lastName];
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE MMMM d, yyyy"];
self.birthdateLabel.text = [dateFormatter stringFromDate:model.birthdate];
}
MVVM: 创建一个ViewModel
像MVC中Format这个逻辑,完全可以脱离VC,从而减少ViewController中的代码逻辑.
@interface PersonViewModel : NSObject
- (instancetype)initWithPerson:(Person *)person;
@property (nonatomic, readonly) Person *person;
@property (nonatomic, readonly) NSString *nameText;
@property (nonatomic, readonly) NSString *birthdateText;
@end
Person在ViewModel中是作为一个属性,而ViewModel本身有VC中要展示的数据nameText与birthdateText
@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
MVVM: 轻量化的ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.nameLabel.text = self.viewModel.nameText;
self.birthdateLabel.text = self.viewModel.birthdateText;
}
MVVM模式的实质
实质就是用一个新的Model,称之为ViewModel,包含了原本MVC中的Model,然后把对数据的逻辑处理和部分业务逻辑,放入这个Model中.ViewController只负责可视化已经处理完善的数据.
MVVM本身也是每一个ViewController对应一个ViewModel,但是对于MVC来讲,其具备了一定性质的ViewModel复用的可能
MVVM的缺点
好多人推崇MVVM,但是并不代表它没有缺点,任何设计模式都有缺陷,唐巧提到MVVM的作者 John Gossman 的批评,应该值得注意
第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。
第二点:对于过大的项目,数据绑定需要花费更多的内存。