从MVC到MVP

栏目: IOS · 发布时间: 4年前

内容简介:以前本人一直用的都是MVC的设计模式去开发应用的。封装MVC的基类等等,和一些工具类配合开发。甚至去过的公司也都是这种方式,就连苹果的基类名字都是以View,Controller(UIView,UIViewController等)结尾的。但是这次发现公司controller层代码量异常的庞大(想找个方法,滑动半天都找不到,好累...,主要是写法不规范,冗余代码太多),虽然重构了基类,从而减重了controller类,但是发现还是过于冗杂。公司的网络请求一个界面有多个,导致一个controller有好多网络请

以前本人一直用的都是MVC的 设计模式 去开发应用的。封装MVC的基类等等,和一些 工具 类配合开发。甚至去过的公司也都是这种方式,就连苹果的基类名字都是以View,Controller(UIView,UIViewController等)结尾的。但是这次发现公司controller层代码量异常的庞大(想找个方法,滑动半天都找不到,好累...,主要是写法不规范,冗余代码太多),虽然重构了基类,从而减重了controller类,但是发现还是过于冗杂。公司的网络请求一个界面有多个,导致一个controller有好多网络请求的代码。之后尝试用mvp设计模式去重构发现好多了,层次分明了,世界清净了哈哈。

那是不是iOS开发只能用MVC的设计模式呢,显然不是的。MVC,MVP,MVVM(统称MVX系列)其实都可以的。其实android现在普遍在用MVP的设计模式,前端(vue等)都在用MVVM的设计模式。

有这么多的设计模式,iOS开发应该选用哪种设计模式呢,哪种更好呢,带着这些问题我们去探索一下这些设计模式在iOS开发上的应用,特点,以及他们不同。看看哪种设计模式更适合自己。

MVC

M:Model,它是模型类,就是有很多属性,每个属性名字和后台返回的字段名相同。

V:View,它是视图类,如继承与UIView类的所有类都可以认为是V层。这个类里存放的都是和视图相关的逻辑代码。

C:Controller,它是控制器类,这里是主要写各种逻辑的地方,这里控制着M层数据源,控制着View的展示等等。

三者关系是,c层持有m层,持有v层

可见C层控制着view的展示,控制着M数据的填充,一些点击事件一些逻辑,甚至网络请求代码等等。这使得C层异常的庞大。为了解决这个问题,我们引入了各种工具类,甚至封装各种基类试图用这些工具类封装的代码去减轻controller。但是事实表明这样做还是不能对controller彻底瘦身,controller层还是庞大。

还有个问题是层次并不是那么的分明,比如controller层是视图控制器,那就控制视图好了嘛,干嘛要负责那么多任务呢。既要负责网络的请求,又要负责各种数据层的逻辑,这有些违反了视图控制器的这个概念。

可见传统的MVC设计模式有着不可避免的两大问题,controller庞大,层次不明。为了解决这个问题,从而引出了MVP的设计模式

MVP

M:Model,它是模型类,就是有很多属性,每个属性名字和后台返回的字段名相同。

V:View,它是视图类,如继承与UIView类的所有类都可以认为是V层,并且Controller也属于V层,即继承与UIView,UIViewController类的所有类都属于V层。这个类里存放的都是和视图相关的逻辑代码。并且controller类里存放的是一些胶水代码(就是起到粘合作用的代码)。

P:Presenter,它是P层,这里是主要写网络请求,数据逻辑的地方。处理和视图无关的数据逻辑等。这个类不该持有v层,也就是不该#import <UIKit/UIKit.h>

三者关系是,v层持有p层,p层持有m层,并回调给v层。

从上面介绍可以看出,MVC中的C层中的网络请求,数据逻辑代码被移动到了MVP中的P层中。这样做一是可以减轻MVC中的C层的代码量,又可以使得层次分明。

下边我们用一些伪代码来进一步探索MVP的应用,其实和MVC一样,我们也需要封装出一套MVP的基类。用这些基类可以使得我们编码更方便。

从MVC到MVP
//MyModel类
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyModel : NSObject

/** 头像 */
@property (copy, nonatomic) NSString *img;
/** 昵称 */
@property (copy, nonatomic) NSString *nickName;
@end

NS_ASSUME_NONNULL_END


//MyVC类
#import "MyVC.h"
#import "MyPresenter.h"

@interface MyVC ()
@property (strong, nonatomic) MyPresenter *presenter;
@end

@implementation MyVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //持有P层
    self.presenter = [[MyPresenter alloc] init];
    [self setUpUI];
    //网络请求
    [self fetchData];
}

- (void)setUpUI{
    //布局代码...
}

- (void)fetchData{
    [self.presenter fetchData:^(MyModel * _Nonnull model, NSError * _Nonnull error) {
        if (error) {
            //出错处理
        }else{
            //数据赋值
            
        }
    }];
}
@end

//MyPresenter类
#import "MyPresenter.h"
#import "MyModel.h"
#import <BSUtilsBaseRequestManager.h>

@implementation MyPresenter
- (void)fetchData:(void(^)(MyModel *model, NSError * _Nonnull error))finishBlk{
    [[BSUtilsBaseRequestManager new] postWithUrl:@"xxx" parmas:@{} finishBlk:^(NSDictionary * _Nonnull responseObject, NSError * _Nonnull error) {
        //json转model
        //数据整理,数据逻辑
        if (finishBlk) {
            finishBlk(model,error);
        }
    }];
}
@end
复制代码

总结

通过比较分析可知,传统MVC,C层代码量庞大,层次不分明。MVP设计模式把网络请求,数据层逻辑抽出来放到P层,这样解决了C层代码量庞大问题,也解决了层次分明问题。

其实采用mvp设计模式后不仅仅解决了c层庞大问题,层次分明问题。而且p层是复用的,比如我们一个地方用到了点赞功能,我们就可以持有点赞功能的p层去调用相应的点赞方法即可。如果是用传统的mvc设计模式,网络请求都是写在了c层,我们每次都得复制粘贴点赞的请求方法,异常的麻烦,如果想复用这段代码,就要考虑写成类方法,并且要考虑耦合性问题,还是比较麻烦的。但是用mvp后所有的网络请求的p层相当于都是复用的了,随时都可以无耦合的调用。

当你用了mvp设计模式后可能有时会发现p层代码量很少,但是却独占一个类,这时候可以考虑p层合并。比如我们有两个界面,一个界面是一级分类,另一个界面是二级分类。这时候两个界面我们可以考虑用一个p层,两个界面的网络请求代码都放到一个层中。但是有时候是无法合并的,因为这个p层和其他p层没有相同的含义,这时候硬是合并是不合理的。这时候确实会存在一个p层就一个网络请求的方法但是却独占一个类,这是没有办法的。但是这样也确实是层次分明了,这个网络请求代码可以复用了,有利也有弊吧。但是我觉得利是大于弊的,比起mvc我还是比较喜欢用mvp的设计模式。


以上所述就是小编给大家介绍的《从MVC到MVP》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

智能革命

智能革命

李彦宏 等 / 中信出版集团 / 2017-5-1 / 68.00元

人类历史上的历次技术革命,都带来了人类感知和认知能力的不断提升,从而使人类知道更多,做到更多,体验更多。以此为标准,李彦宏在本书中将人工智能定义为堪比任何一次技术革命的伟大变革,并且明确提出,在技术与人的关系上,智能革命不同于前几次技术革命,不是人去适应机器,而是机器主动来学习和适应人类,并同人类一起学习和创新这个世界。“人工智能”正式写入2017年政府工作报告,折射出未来人工智能产业在我国经济发......一起来看看 《智能革命》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具