iOS的 MVP模式 學習

這兩天時間寬松一點,所以我也來學學MVP的設計模式,有人說是架構,管他呢,好用就行。so,開干! 后邊有OC版本的demo

  1. 打開了Google,搜了一下關鍵字 MVP iOS,然后發(fā)現(xiàn)了一些文章,最后是這篇文章帶給我對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發(fā)命令來控制view的交互,要你隱藏就隱藏,叫你show 你就乖乖的show)
    • presenter擁有對 view交互的邏輯(就是上面說的意思)
    • presenter跟model層通信,并將數(shù)據(jù)轉化成對適應UI的數(shù)據(jù)并更新view
    • presenter不需要依賴UIKit
    • view層是單一,因為它是被動接受命令,沒有主動能力

如下


The MVP pattern

presenter 作為業(yè)務邏輯的處理者,首先要向model層拿數(shù)據(jù),所以它將可以向model層通信。其次,UI的處理權移交給了它,所以它需要與view成通訊,發(fā)送命令改變UI。同時,UI的響應將觸發(fā)業(yè)務邏輯的處理,所以view 層向presenter層通訊,告訴他用戶做了什么操作,需要你反饋對應的數(shù)據(jù)來更新UI。這樣就完成了從用戶交互獲得交互反饋到整個業(yè)務邏輯。

  1. 說啥都是廢話,交出代碼,我們還能做朋友
    首先看下結構
三個主要類和一個協(xié)議

UserViewProtocol 協(xié)議定義了一下方法,這些方法其實就是presenter對view層發(fā)送的命令
#import <Foundation/Foundation.h>
@protocol UserViewProtocol <NSObject>
-(void) userViewDataSource:(NSArray*)data;
-(void) showIndicator;
-(void) hideIndicator;
-(void) showEmptyView;
@end

UserService 類是用來請求數(shù)據(jù)給presenter的,也能算是model層吧。我就只定義了一個方法。

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

這一層,其實也可以很復雜,這就涉及網絡層的架構了,可以去看看casatwy大神關于網絡層架構的思路,我也正在學習 。

ViewController類則是UI層,它實現(xiàn)了tableview自己的協(xié)議,還實現(xiàn)了用戶交互的協(xié)議 UserViewProtocol,也就說,presenter向UI層發(fā)送命令,其實是發(fā)給UI層的viewController,實際上是控制器來被動的更新UI。這個不管是MVC還是MVP,view的實際控制權應該都是viewController,這個理解應該沒錯吧。
協(xié)議中的幾個方法實現(xiàn)如下。

-(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 方法,這個方法是對外公開的,目的就是為了將實現(xiàn)了UserViewProtocol 協(xié)議的對象(其實應該就是控制器,因為view的直接操作者就是view Controller)綁定到presenter 上,說白了就是presenter 可以直接拿到實現(xiàn)了UserViewProtocol 協(xié)議的對象,并且向他發(fā)送命令(協(xié)議實現(xiàn)的方法,前面有說到),具體該方法的實現(xiàn)

@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 來打破循環(huán)引用,這跟我們平時使用委托協(xié)議( delegate)是一樣的,只是名字換成了attachView 而已。

再來說fetchData方法,公開這個方法,只是為了數(shù)據(jù)請求有個統(tǒng)一的接口,而不需要presenter分開多次調用,presenter自己處理所有事情,不讓viewController參和進來。具體實現(xiàn)就看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;
}

這個私有方法是將原始數(shù)據(jù)轉換成UI所需要的數(shù)據(jù),這樣UI拿到數(shù)據(jù)就可以直接使用,而不用做各種判斷,邏輯依然放在了presenter中。而且,這個數(shù)據(jù)處理可以做成協(xié)議,輸出不同UI需要的數(shù)據(jù),這個也可以看casatwy大神 關于view架構的文章。

這就是我的一些簡單理解!有錯誤歡迎糾正。最后,還有demo沒上啊,就想跑
demo在這里https://github.com/HecvStyle/MVPDemo

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容