iOS的 MVP模式 学习

这两天时间宽松一点,所以我也来学学MVP的设计模式,有人说是架构,管他呢,好用就行。so,开干! 后边有OC版本的demo

  1. 打开了Google,搜了一下关键字 MVP iOS,然后发现了一些文章,最后是这篇文章带给我对MVP 的一些认识。
  2. MVP似乎有好多的变种,作者所说的这种有如下特点:
    (原文如下:)
    • the view part of the MVP consists of both UIViews and UIViewController
    • the view delegates user interactions to the presenter
    • the presenter contains the logic to handle user interactions
    • the presenter communicates with model layer, converts the data to UI friendly format, and updates the view
    • the presenter has no dependencies to UIKit
    • the view is passive (dump)
      稍微翻译一下
    • MVP的 V 层是由UIViewController 和UIView 共同组成
    • view 将委托presenter 对它自己的操作,(简单来说就是presenter发命令来控制view的交互,要你隐藏就隐藏,叫你show 你就乖乖的show)
    • presenter拥有对 view交互的逻辑(就是上面说的意思)
    • presenter跟model层通信,并将数据转化成对适应UI的数据并更新view
    • presenter不需要依赖UIKit
    • view层是单一,因为它是被动接受命令,没有主动能力

如下


The MVP pattern

presenter 作为业务逻辑的处理者,首先要向model层拿数据,所以它将可以向model层通信。其次,UI的处理权移交给了它,所以它需要与view成通讯,发送命令改变UI。同时,UI的响应将触发业务逻辑的处理,所以view 层向presenter层通讯,告诉他用户做了什么操作,需要你反馈对应的数据来更新UI。这样就完成了从用户交互获得交互反馈到整个业务逻辑。

  1. 说啥都是废话,交出代码,我们还能做朋友
    首先看下结构
三个主要类和一个协议

UserViewProtocol 协议定义了一下方法,这些方法其实就是presenter对view层发送的命令
#import <Foundation/Foundation.h>
@protocol UserViewProtocol <NSObject>
-(void) userViewDataSource:(NSArray*)data;
-(void) showIndicator;
-(void) hideIndicator;
-(void) showEmptyView;
@end

UserService 类是用来请求数据给presenter的,也能算是model层吧。我就只定义了一个方法。

-(void)getUserInfosSuccess:(SuccessHandler )success andFail:(FailHandler) failure

这一层,其实也可以很复杂,这就涉及网络层的架构了,可以去看看casatwy大神关于网络层架构的思路,我也正在学习 。

ViewController类则是UI层,它实现了tableview自己的协议,还实现了用户交互的协议 UserViewProtocol,也就说,presenter向UI层发送命令,其实是发给UI层的viewController,实际上是控制器来被动的更新UI。这个不管是MVC还是MVP,view的实际控制权应该都是viewController,这个理解应该没错吧。
协议中的几个方法实现如下。

-(void)userViewDataSource:(NSArray*)data{
 self.friendlyUIData = data;
 [self.tableview reloadData];
}
-(void) showIndicator{
 self.indicator.hidden = NO;
}
-(void) hideIndicator{
 self.indicator.hidden = YES;
}
-(void) showEmptyView{
 UIAlertController *alertView = [UIAlertController alertControllerWithTitle:@"Alert" message:@"show empty view" preferredStyle:UIAlertControllerStyleAlert];
 [alertView addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
 [self presentViewController:alertView animated:YES completion:^{
 }];
}

另外,在viewDidload中,调用了presenter的两个public 方法

 self.presenter = [Presenter new];
 [self.presenter attachView:self];
 [self.presenter fetchData];

那就来看看Presenter类,这个类我在demo中加了不少的注释,主要是为了理清自己的思路
先说attachView 方法,这个方法是对外公开的,目的就是为了将实现了UserViewProtocol 协议的对象(其实应该就是控制器,因为view的直接操作者就是view Controller)绑定到presenter 上,说白了就是presenter 可以直接拿到实现了UserViewProtocol 协议的对象,并且向他发送命令(协议实现的方法,前面有说到),具体该方法的实现

@interface Presenter()
@property (nonatomic,strong) UserService *userService;
@property (nonatomic,weak) id<UserViewProtocol> attachView;
@end
-(void)attachView:(id <UserViewProtocol>)view{
 self.attachView = view;
 self.userService  = [UserService new];
}

注意这里用了weak 来修饰attachView 树形,因为presenter和 viewController相互持有,所以必须要通过weak 来打破循环引用,这跟我们平时使用委托协议( delegate)是一样的,只是名字换成了attachView 而已。

再来说fetchData方法,公开这个方法,只是为了数据请求有个统一的接口,而不需要presenter分开多次调用,presenter自己处理所有事情,不让viewController参和进来。具体实现就看demo

最后说一下

-(NSArray *)processOriginDataToUIFriendlyData:(NSArray *) originData{
 NSMutableArray *friendlyUIData = [NSMutableArray new];
 for (NSDictionary *dic in originData) {
  if ([[dic valueForKey:@"gender"] isEqualToString:@"males"]) {
   [friendlyUIData addObject:dic];
  }
 }
 return friendlyUIData;
}

这个私有方法是将原始数据转换成UI所需要的数据,这样UI拿到数据就可以直接使用,而不用做各种判断,逻辑依然放在了presenter中。而且,这个数据处理可以做成协议,输出不同UI需要的数据,这个也可以看casatwy大神 关于view架构的文章。

这就是我的一些简单理解!有错误欢迎纠正。最后,还有demo没上啊,就想跑
demo在这里https://github.com/HecvStyle/MVPDemo

--------end--------

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容