MVC、MVVM模式
经典的MVC模式如下图:
在苹果的设想里MVC
View:是xib或者storyboard。负责整个页面上的view(button,lable)以及其布局。
Controller:负责处理点击事件,view页面动态管理,处理数据,网络请求。业务逻辑。
Model:数据模型
优点很明显:层级简单,分工明确,开发快捷,便于掌握。
纯代码实现MC
然而我们对xib和storyboard深恶痛绝,其git管理麻烦,不方便代码复用。最重要的不方便在view上使用各种设计模式,阻碍我们进步。所以我们当然选择纯代码了。
然后我们将页面布局写在controller中
分层如下:
Controller:负责处理点击事件,view页面动态管理。 负责整个页面上的view(button,lable)以及其布局。处理数据,网络请求。业务逻辑。
Model:数据模型
这样事件少传一层,写起来太方便了,「大笑」
也样就形成了著名的Massive View Controller。
代码类似
@interface HBDownFileViewController ()
@property (nonatomic,strong) UIView *headerView;
@property (nonatomic,strong) UIButton *openFileButton;
@end
@implementation HBDownFileViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpUI];
}
-(void)setUpUI{
[self.view addSubview:self.headerView];
[self.view addSubview:self.fileView];
[self.fileView addSubview:self.openFileButton];
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.mas_equalTo(self.view);
make.height.mas_equalTo(60);
}];
[self.openFileButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.headerView).offset(16);
make.right.mas_equalTo(self.headerView).offset(-16);
make.bottom.mas_equalTo(self.headerView.mas_bottom).offset(-32);
make.height.mas_equalTo(40);
}];
}
#pragma mark - set&get
- (UIView *)headerView
{
if (!_headerView) {
_headerView = [[UIView alloc]init];
}
return _headerView;
}
- (UIButton *)openFileButton
{
if (!_openFileButton) {
_openFileButton = [[UIButton alloc]init];
_openFileButton.titleLabel.font = [UIFont systemFontOfSize:14];
}
return _openFileButton;
}
@end
纯代码的MVC
既然使用xib和storyboard可以实现MVC,那么纯代码当然也可以。我们只需要一个view类来管理每个页面的布局以及简单的页面逻辑。
View:纯代码UIView。负责整个页面上的view(button,lable)的设置以及其布局。
Controller:负责处理点击事件,view页面动态管理。处理数据,网络请求
Model:数据模型
MVC进阶
方法一、Model多做一些
Controller处理数据,网络请求。还要处理页面逻辑。Controller还是很庞大啊。
我们可以让Model来处理数据,网络请求。这样能减轻一下Controller的负担。
View:纯代码UIView。负责整个页面上的view(button,lable)的设置以及其布局。
Controller:负责处理点击事件,view页面动态管理。业务逻辑。
Model:数据模型。处理数据,网络请求。
这基本上能满足大多数开发情景了。
真的有少数Controller非常大,各种设计模式完全可以用起来。
然鹅,精通设计模式的人,实在太少了,我们还是需要简单粗暴的办法(更死的划分、限制)
方法二、MVP
Controller毕竟还负担着业务逻辑。还是抽出来好了。于是MVP横空出世。
本来名字应该叫MVPC,但是View和Controller都可以看做View。
View:纯代码UIView。负责整个页面上的view(button,lable)的设置以及其布局。
Controller:负责处理点击事件,view页面动态管理。
Presenter:业务逻辑。
Model:数据模型。处理数据,网络请求。
能不能直接合并View和Controller呢,感觉合并后好像MVC只是职测有点差别而已。
方法三、MVVM
毕竟Model还是要保持纯洁的。
Presenter应该是和ViewModel合并来减少层级,还是保持拆分保持单一职责。那就需要根据实际情况来权衡了。
如果再合并View和Controller呢,那还是回到了MVC。
View:纯代码UIView。负责整个页面上的view(button,lable)的设置以及其布局。
Controller:负责处理点击事件,view页面动态管理。
Presenter:业务逻辑。
ViewModel:处理数据(负责view的数据处理),网络请求。
Model:数据模型。
总结
对于MVVM和MVP来说,如果是为了解决View与Controller合并带来的Massive View Controller问题,那么他们也只是一个MVC模式。
相当于让View添加了一些职责(如果将处理点击事件,view页面动态管理)。改变一下名字「手动狗头」。
如果View和Controller 保持拆分状态,就需要权衡层级增加带来数据传递带来的成本增加、分层带来的好处。
组件化和MVC这些不在一个层级上。
参考
1、 iOS 架构模式–解密 MVC,MVP,MVVM以及VIPER架构
2、iOS架构入门 - MVC模式实例演示 不谋而合
一位能把简单的东西讲的复杂的大神,VIPER的解读应该错了。