iOS開(kāi)發(fā)之淺談MVVM的架構(gòu)設(shè)計(jì)與團(tuán)隊(duì)協(xié)作 -電腦資料

電腦資料 時(shí)間:2019-01-01 我要投稿
【m.clearvueentertainment.com - 電腦資料】

    今天寫(xiě)這篇博客是想達(dá)到拋磚引玉的作用,想與大家交流一下思想,相互學(xué)習(xí),博文中有不足之處還望大家批評(píng)指正,

iOS開(kāi)發(fā)之淺談MVVM的架構(gòu)設(shè)計(jì)與團(tuán)隊(duì)協(xié)作

。本篇博客的內(nèi)容沿襲以往博客的風(fēng)格,也是以干貨為主,偶爾扯扯咸蛋(哈哈~不好好工作又開(kāi)始發(fā)表博客啦~)。

    由于本人項(xiàng)目經(jīng)驗(yàn)有限,關(guān)于架構(gòu)設(shè)計(jì)方面的東西理解有限,我個(gè)人對(duì)MVVM的理解主要是借鑒于之前的用過(guò)的MVC的Web框架~在學(xué)校的時(shí)候用過(guò)ThinkPHP框架,和SSH框架,都是MVC的架構(gòu)模式,今天MVVM與傳統(tǒng)的MVC可謂是極為相似,也可以說(shuō)是兄弟關(guān)系,也就是一家人了。

    說(shuō)道架構(gòu)設(shè)計(jì)和團(tuán)隊(duì)協(xié)作,這個(gè)對(duì)App的開(kāi)發(fā)還是比較重要的。即使作為一個(gè)專(zhuān)業(yè)的搬磚者,前提是你這磚搬完放在哪?不只是Code有框架,其他的東西都是有框架的,比如橋梁等等神馬的~在這兒就不往外扯了。一個(gè)好的工程框架不進(jìn)可以提高團(tuán)隊(duì)的協(xié)作效率,同時(shí)還可以減少代碼的冗余度和耦合性,合理的分工與系統(tǒng)的架構(gòu)設(shè)計(jì)是少不了的。

    至于團(tuán)隊(duì)協(xié)作不僅僅是有SVN或者Git這些版本控制工具就行的,至于如何在iOS開(kāi)發(fā)中使用SVN,請(qǐng)參考之前的博客(iOS開(kāi)發(fā)之版本控制(SVN))。一個(gè)團(tuán)隊(duì)可以高效的工作,本人覺(jué)得交流是最為重要的,團(tuán)隊(duì)中的每個(gè)人都比較和氣,而且交流上沒(méi)有什么障礙(不過(guò)有的團(tuán)隊(duì)中總有幾個(gè)合不來(lái)的人),交流在團(tuán)隊(duì)中最為重要。至于SVN怎么用,那都不是事兒!

    好了今天就以我寫(xiě)的一個(gè)Demo來(lái)淺談一下iOS開(kāi)發(fā)中的架構(gòu)設(shè)計(jì)和團(tuán)隊(duì)協(xié)作,今天的咸蛋先到這兒,切入今天的話題。

    為了寫(xiě)今天的博客我花了點(diǎn)時(shí)間做了個(gè)工程,這個(gè)工程后臺(tái)的接口用的 的API來(lái)進(jìn)行測(cè)試的,在本文的后面也會(huì)跟上GitHub的分享鏈接。OK~說(shuō)的高大上一些就是,仁者見(jiàn)仁智者見(jiàn)智,交流思想,共同學(xué)習(xí)。

    一、小酌一下MVVM

    在這呢也不贅述什么是MVC,神馬又是MVVM了,在百度上谷歌一下一抓一大把,在這兒就簡(jiǎn)單的提上一嘴。下面的Demo用的就是MVVM的架構(gòu)模式。

    Model層是少不了的了,我們得有東西充當(dāng)DTO(數(shù)據(jù)傳輸對(duì)象),當(dāng)然,用字典也是可以的,編程么,要靈活一些。Model層是比較薄的一層,如果學(xué)過(guò)Java的小伙伴的話,對(duì)JavaBean應(yīng)該不陌生吧。

    ViewModel層,就是View和Model層的粘合劑,他是一個(gè)放置用戶輸入驗(yàn)證邏輯,視圖顯示邏輯,發(fā)起網(wǎng)絡(luò)請(qǐng)求和其他各種各樣的代碼的極好的地方。說(shuō)白了,就是把原來(lái)ViewController層的業(yè)務(wù)邏輯和頁(yè)面邏輯等剝離出來(lái)放到ViewModel層。

    View層,就是ViewController層,他的任務(wù)就是從ViewModel層獲取數(shù)據(jù),然后顯示。

    上面對(duì)MVVM就先簡(jiǎn)單的這么一說(shuō),好好的理解并應(yīng)用的話,還得實(shí)戰(zhàn)。

    二、關(guān)于工程中是否使用StoryBoard的論述

    從網(wǎng)上經(jīng)常看到說(shuō)不推薦使用StoryBoard或者Xib,推薦用純代碼手寫(xiě)。個(gè)人認(rèn)為這種觀點(diǎn)是和蘋(píng)果設(shè)計(jì)StoryBoard的初衷相悖的,在我做過(guò)的項(xiàng)目中是以StoryBoard為主,xib為輔,然后用代碼整合每個(gè)StoryBoard.

    舉一個(gè)用Storyboard好處的例子就OK了,給控件添加約束,如果用Storyboard完成那是分分秒的事情,而用代碼的添加約束的話是何等的惡心,純代碼寫(xiě)的話會(huì)把大量的時(shí)間花在寫(xiě)UI上,而且技術(shù)含量是比較低的,這個(gè)個(gè)人認(rèn)為沒(méi)什么必要。在團(tuán)隊(duì)合作中負(fù)責(zé)UI開(kāi)發(fā)的小伙伴只需沒(méi)人負(fù)責(zé)一個(gè)Storyboard,各開(kāi)發(fā)各的,用SVN提交時(shí)把下面的勾(如下圖)去掉即可,這樣用Storyboard是沒(méi)有問(wèn)題的。然后再用代碼進(jìn)行整合就OK了。如果你在你的工程中加入了新的資源文件的話,用XCode自帶的SVN提交的話需要吧Project Setting文件一并提交。

    三、實(shí)戰(zhàn)MVVM(用Xcode創(chuàng)建的Group是虛擬的文件夾,為了便于維護(hù),建議創(chuàng)建物理文件夾,然后再手動(dòng)引入)

    1.下面通過(guò)一個(gè)實(shí)例來(lái)體會(huì)一下MVVM架構(gòu)模式,下面是該工程的一級(jí)目錄如下,每層之間的交互是用Block的形式來(lái)實(shí)現(xiàn)的

    工程目錄說(shuō)明:

    1.Request:文件夾下存儲(chǔ)網(wǎng)絡(luò)請(qǐng)求的類(lèi),下面會(huì)給出具體的實(shí)現(xiàn)

    2.Config:就是工程的配置文件

    3.Resource:就是工程的資源文件,下面有圖片資源和Storyboard文件資源

    4.Tools是:工具文件類(lèi),存放工具類(lèi),比如數(shù)據(jù)正則匹配等。

    5.Vender:存放第三方類(lèi)庫(kù)

    6.Model:這個(gè)就不多說(shuō)了

    7.ViewController:存放ViewController類(lèi)資源文件,也就是View層

    8.ViewModel:存放各種業(yè)務(wù)邏輯和網(wǎng)絡(luò)請(qǐng)求

    2.詳解Request:Request負(fù)責(zé)網(wǎng)絡(luò)請(qǐng)求的東西,具體如下:

    NetRequestClass是存放網(wǎng)絡(luò)請(qǐng)求的代碼,本工程用的AF,因?yàn)楸竟こ讨皇且粋(gè)Demo,所以就只封裝了監(jiān)測(cè)網(wǎng)絡(luò)狀態(tài),GET請(qǐng)求,POST請(qǐng)求方法,根據(jù)現(xiàn)實(shí)需要,還可以封裝上傳下載等類(lèi)方法。

    NetRequestClass.h中的代碼如下:

    1 //

    2 // NetRequestClass.h

    3 // MVVMTest

    4 //

    5 // Created by 李澤魯 on 15/1/6.

    6 // Copyright (c) 2015年 李澤魯. All rights reserved.

    7 //

    8

    9 #import

    10

    11 @interface NetRequestClass : NSObject

    12

    13 #pragma 監(jiān)測(cè)網(wǎng)絡(luò)的可鏈接性

    14 + (BOOL) netWorkReachabilityWithURLString:(NSString *) strUrl;

    15

    16 #pragma POST請(qǐng)求

    17 + (void) NetRequestPOSTWithRequestURL: (NSString *) requestURLString

    18            WithParameter: (NSDictionary *) parameter

    19         WithReturnValeuBlock: (ReturnValueBlock) block

    20          WithErrorCodeBlock: (ErrorCodeBlock) errorBlock

    21           WithFailureBlock: (FailureBlock) failureBlock;

    22

    23 #pragma GET請(qǐng)求

    24 + (void) NetRequestGETWithRequestURL: (NSString *) requestURLString

    25            WithParameter: (NSDictionary *) parameter

    26        WithReturnValeuBlock: (ReturnValueBlock) block

    27         WithErrorCodeBlock: (ErrorCodeBlock) errorBlock

    28          WithFailureBlock: (FailureBlock) failureBlock;

    29

    30 @end

    NetRequestClass.m中的代碼如下:

    1 //

    2 // NetRequestClass.m

    3 // MVVMTest

    4 //

    5 // Created by 李澤魯 on 15/1/6.

    6 // Copyright (c) 2015年 李澤魯. All rights reserved.

    7 //

    8

    9 #import "NetRequestClass.h"

    10

    11 @interface NetRequestClass ()

    12

    13 @end

    14

    15

    16 @implementation NetRequestClass

    17 #pragma 監(jiān)測(cè)網(wǎng)絡(luò)的可鏈接性

    18 + (BOOL) netWorkReachabilityWithURLString:(NSString *) strUrl

    19 {

    20  __block BOOL netState = NO;

    21

    22  NSURL *baseURL = [NSURL URLWithString:strUrl];

    23

    24  AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];

    25

    26  NSOperationQueue *operationQueue = manager.operationQueue;

    27

    28  [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

    29    switch (status) {

    30      case AFNetworkReachabilityStatusReachableViaWWAN:

    31      case AFNetworkReachabilityStatusReachableViaWiFi:

    32        [operationQueue setSuspended:NO];

    33        netState = YES;

    34        break;

    35      case AFNetworkReachabilityStatusNotReachable:

    36        netState = NO;

    37      default:

    38        [operationQueue setSuspended:YES];

    39        break;

    40    }

    41  }];

    42

    43  [manager.reachabilityManager startMonitoring];

    44

    45  return netState;

    46 }

    47

    48

    49 /***************************************

    50 在這做判斷如果有dic里有errorCode

    51 調(diào)用errorBlock(dic)

    52 沒(méi)有errorCode則調(diào)用block(dic

    53 ******************************/

    54

    55 #pragma --mark GET請(qǐng)求方式

    56 + (void) NetRequestGETWithRequestURL: (NSString *) requestURLString

    57            WithParameter: (NSDictionary *) parameter

    58        WithReturnValeuBlock: (ReturnValueBlock) block

    59         WithErrorCodeBlock: (ErrorCodeBlock) errorBlock

    60          WithFailureBlock: (FailureBlock) failureBlock

    61 {

    62  AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];

    63

    64  AFHTTPRequestOperation *op = [manager GET:requestURLString parameters:parameter success:^(AFHTTPRequestOperation *operation, id responseObject) {

    65    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];

    66    DDLog(@"%@", dic);

    67

    68    block(dic);

    69

    70  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    71    failureBlock();

    72  }];

    73

    74  op.responseSerializer = [AFHTTPResponseSerializer serializer];

    75

    76  [op start];

    77

    78 }

    79

    80 #pragma --mark POST請(qǐng)求方式

    81

    82 + (void) NetRequestPOSTWithRequestURL: (NSString *) requestURLString

    83            WithParameter: (NSDictionary *) parameter

    84         WithReturnValeuBlock: (ReturnValueBlock) block

    85          WithErrorCodeBlock: (ErrorCodeBlock) errorBlock

    86           WithFailureBlock: (FailureBlock) failureBlock

    87 {

    88  AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];

    89

    90  AFHTTPRequestOperation *op = [manager POST:requestURLString parameters:parameter success:^(AFHTTPRequestOperation *operation, id responseObject) {

    91    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];

    92

    93    DDLog(@"%@", dic);

    94

    95    block(dic);

    96    /***************************************

    97     在這做判斷如果有dic里有errorCode

    98     調(diào)用errorBlock(dic)

    99     沒(méi)有errorCode則調(diào)用block(dic

    100     ******************************/

    101

    102  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    103    failureBlock();

    104  }];

    105

    106  op.responseSerializer = [AFHTTPResponseSerializer serializer];

    107

    108  [op start];

    109

    110 }

    111

    112

    113

    114

    115 @end

    3.詳解Config:創(chuàng)建pch文件,和Config.h文件

    pch文件引入常用的頭文件,內(nèi)容如下:

    1 //

    2 // PrefixHeader.pch

    3 // MVVMTest

    4 //

    5 // Created by 李澤魯 on 15/1/6.

    6 // Copyright (c) 2015年 李澤魯. All rights reserved.

    7 //

    8

    9 #ifndef MVVMTest_PrefixHeader_pch

    10 #define MVVMTest_PrefixHeader_pch

    11

    12 #import"AFNetworking.h"

    13 #import "UIKit+AFNetworking.h"

    14 #import "Config.h"

    15

    16 #import "NetRequestClass.h"

    17 #import "SVProgressHUD.h"

    18 #endif

    Config.h中就是各種宏定義和各種枚舉類(lèi)型和block類(lèi)型,代碼如下:

    1 //

    2 // Config.h

    3 // MVVMTest

    4 //

    5 // Created by 李澤魯 on 15/1/6.

    6 // Copyright (c) 2015年 李澤魯. All rights reserved.

    7 //

    8

    9 #ifndef MVVMTest_Config_h

    10 #define MVVMTest_Config_h

    11

    12 //定義返回請(qǐng)求數(shù)據(jù)的block類(lèi)型

    13 typedef void (^ReturnValueBlock) (id returnValue);

    14 typedef void (^ErrorCodeBlock) (id errorCode);

    15 typedef void (^FailureBlock)();

    16 typedef void (^NetWorkBlock)(BOOL netConnetState);

    17

    18 #define DDLog(xx, ...) NSLog(@"%s(%d): " xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)

    19

    20 //accessToken

    21 #define ACCESSTOKEN @"你自己的access_token"

    22

    23 //請(qǐng)求公共微博的網(wǎng)絡(luò)接口

    24 #define REQUESTPUBLICURL @www.2cto.com"

    25

    26 #define SOURCE @"source"

    27 #define TOKEN @"access_token"

    28 #define COUNT @"count"

    29

    30 #define STATUSES @"statuses"

    31 #define CREATETIME @"created_at"

    32 #define WEIBOID @"id"

    33 #define WEIBOTEXT @"text"

    34 #define USER @"user"

    35 #define UID @"id"

    36 #define HEADIMAGEURL @"profile_image_url"

    37 #define USERNAME @"screen_name"

    38

    39 #endif

最新文章