iOS 降低viewController颗粒度

随着业务代码的增多,viewcontroller 变得越来越臃肿,使得后续维护变得困难。 每次新增或者改动,最简单就是在原有基础上新增或改动,但是这并非正确,当然每次改动就重构一次,虽然理想但是不太现实。本文通过对各种架构模式进行探讨,使得不降低阅读力的情况下,减少各个类的代码量。

传统的开发步骤,新建一个vieController,通过接口请求,将数据封装成数据模型,渲染在tableview的cell上,viewController承担了数据的获取和处理,以及页面加载,显示,交互逻辑,整体代码都在viewController上

1.MVC

24c32d90d20161bd813bc80e73aaae29~tplv-t2oaga2asx-zoom-in-crop-mark-1304-0-0-0.image.png

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层的业务逻辑

a44d75112269aac5568317023c166ba8~tplv-t2oaga2asx-zoom-in-crop-mark-1304-0-0-0.image.png

扫描二维码关注公众号,回复: 13798488 查看本文章

b0ba97a831a1c5a3d2277dc8b782dec0~tplv-t2oaga2asx-zoom-in-crop-mark-1304-0-0-0.image.png

根据图片可以看出,在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去实现,这里不再展开

ecdf968fe089eb30ca8c74c062a75814~tplv-t2oaga2asx-zoom-in-crop-mark-1304-0-0-0.image.gif

MVVM各层的职责和MVP的类似,VM对应P层,只是在MVVM的View层多了数据绑定的操作

猜你喜欢

转载自juejin.im/post/7087592654326186021