随着业务代码的增多,viewcontroller 变得越来越臃肿,使得后续维护变得困难。 每次新增或者改动,最简单就是在原有基础上新增或改动,但是这并非正确,当然每次改动就重构一次,虽然理想但是不太现实。本文通过对各种架构模式进行探讨,使得不降低阅读力的情况下,减少各个类的代码量。
传统的开发步骤,新建一个vieController,通过接口请求,将数据封装成数据模型,渲染在tableview的cell上,viewController承担了数据的获取和处理,以及页面加载,显示,交互逻辑,整体代码都在viewController上
1.MVC
MVC模式,可以将数据的获取,封装,加工逻辑放在model里面,视图相关的都放在view里,Controller 只用处理数据同步和view的操作事件,这样可以降低Controller的代码量,同时view 和model也可以做到复用的可能,但是MVC也有问题
举例如下
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BlogCellHelper *cellHelper = self.blogs[indexPath.row];
BlogTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ReuseIdentifier];
cell.title = cellHelper.blogTitleText;
cell.summary = cellHelper.blogSummaryText;
cell.likeState = cellHelper.isLiked;
cell.likeCountText = cellHelper.blogLikeCountText;
cell.shareCountText = cellHelper.blogShareCountText;
//点赞的业务逻辑
__weak typeof(cell) weakCell = cell;
[cell setDidLikeHandler:^{
if (cellHelper.blog.isLiked) {
[self.tableView showToastWithText:@"你已经赞过它了~"];
} else {
[[UserAPIManager new] likeBlogWithBlogId:cellHelper.blog.blogId completionHandler:^(NSError *error, id result) {
if (error) {
[self.tableView showToastWithText:error.domain];
} else {
cellHelper.blog.likeCount += 1;
cellHelper.blog.isLiked = YES;
//点赞的业务展示
weakCell.likeState = cellHelper.blog.isLiked;
weakCell.likeCountText = cellHelper.blogTitleText;
}
}];
}
}];
return cell;
}
复制代码
点赞的功能,通过cell的按钮事件改变数据源,这就使得view层和model层耦合起来,不能达到我们期望的view,model解耦的目的,另外对于复杂界面或者复杂的数据处理,使得View,model变得臃肿。
2.MVP
MVC的缺点在于并没有区分业务逻辑和业务展示, 这对单元测试很不友好. MVP针对以上缺点做了优化, 它将业务逻辑和业务展示也做了一层隔离, 对应的就变成了MVCP.
M和V功能不变, 原来的C现在只负责布局, 而所有的业务逻辑全都转移到了P层。P层处理完了业务逻辑,如果要更改view的显示,那么可以通过回调来实现,这样可以减轻耦合,同时可以单独测试P层的业务逻辑
根据图片可以看出,在MVC基础上,viewController 持有view层 和Present层,present 和model层交互获取数据,并加工数据,通过代理将View层进行显示。在view中子单元,以常见的UITableCell为例,cell其实不需要获取整个数据模型,只是需要数据模型中的几个属性值,这样的话就在cell与数据模型中间添加一层Present,将cell与数据模型解耦,cell就可以真正意义上实现重用。
3.MVVM
MVVM是在MVP基础上发展而来,那为什么要设计这种模式呢,以点赞为例,点击cell按钮--->调用P的点赞逻辑---->点赞成功后,P改变M的数据--->P回调Cell的代理方法改变cell的显示(点赞成功,赞的个数加1,同时点赞数变红,否则不改变赞的个数也不变色) 上面就是一个事件完整过程,可以看到要通过四步来完成,而且每次都要把P的状态同步到view,当事件多起来的时候,这样写就很麻烦了。那有没有一种简单的机制,让view的行为和状态和P的行为状态同步呢?
答案就是MVVM的binder机制。MVVM在实现中常常使用RAC去实现,这里不再展开
MVVM各层的职责和MVP的类似,VM对应P层,只是在MVVM的View层多了数据绑定的操作