MVVM的特別注意(轉(zhuǎn))

在學(xué)習(xí)MVVM的時候首先提出幾個問題:

MVVM到底是什么?它和MVC有什么區(qū)別?

MVVM中VM到底是個什么角色?它和Controller或者M(jìn)anager有什么區(qū)別哥牍?

ViewController在MVVM中扮演怎樣角色?Api數(shù)據(jù)請求放在哪里嗅辣?數(shù)據(jù)流向如何撼泛?

MVVM簡介

關(guān)于MVVM,相信大家或多或少都有了解愿题。引用MVVM介紹文中一圖:

受MVC或MVP架構(gòu)的影響蛙奖,對MVVM最初印象以為這是一個以ViewModel為核心潘酗,處理View和Model的開發(fā)架構(gòu)。于是乎在原有MVC的基礎(chǔ)上雁仲,創(chuàng)建了一個所謂的ViewModel對象仔夺,然后把ViewController中的代碼移到ViewModel中攒砖,在ViewModel里面處理View以及Model的所有邏輯骆膝。畢竟大家都在說MVVM可以為ViewController瘦身灶体,這ViewController就剩創(chuàng)建ViewModel的代碼掐暮,嗯,夠瘦身路克,這就是MVVM!

慢慢的瓢宦,發(fā)現(xiàn)有什么地方不對灰羽,哪里不對?第一想法就是ViewController的定位玫镐,View怠噪?不是,Controller傍念?也不是憋槐!畢竟它就創(chuàng)建ViewModel,好像與View阳仔、Model也沒啥關(guān)系。拋開ViewController不談驳概,突然發(fā)現(xiàn)這樣的ViewModel、Model以及View不就是MVC更卒,一個以ViewModel為中心的MVC稚照!

錯在哪里

核心問題就在于對ViewModel角色的定位不清俯萌!基于MVVM設(shè)計思路上枕,ViewModel存在目的在于抽離ViewController中展示業(yè)務(wù)邏輯,而不是替代ViewController棋恼,其它視圖操作業(yè)務(wù)等還是應(yīng)該放在ViewController中實現(xiàn)锈玉。

既然不負(fù)責(zé)視圖操作邏輯,ViewModel中就不應(yīng)該存在任何View對象师崎,更不應(yīng)該存在Push/Present等視圖跳轉(zhuǎn)邏輯椅棺。因此,ViewModel中絕不應(yīng)該存在任何視圖操作相關(guān)的代碼

@interface?ViewModel?:?NSObject

//?viewmodel中切不可存在view對象昼汗,更不該出現(xiàn)push或者present代碼

-?(instancetype)initWithTableView:(UITableView?*)tableView;

@end

很簡單鬼雀,處理視圖展示邏輯,ViewModel負(fù)責(zé)將數(shù)據(jù)業(yè)務(wù)層提供的數(shù)據(jù)轉(zhuǎn)化為界面展示所需的VO鞋吉。其與View一一對應(yīng)励烦,沒有View就沒有ViewModel

比如赊锚,數(shù)據(jù)業(yè)務(wù)層傳遞一個含有性別屬性sex的DO對象屉栓,0表示男, 1表示女友多。ViewModel的職責(zé)就是將其轉(zhuǎn)化為展示層可顯示的VO對象

self.personVO.sex = personDO.sex == 0 ? @"男": @"女";

ViewModel和View一起組成DDD(Model-Driven Design)領(lǐng)域驅(qū)動架構(gòu)體系中的Presentation展示層域滥。在iOS中蜈抓,數(shù)據(jù)流向可以表示為ViewModel->ViewController->View昂儒,ViewController負(fù)責(zé)連接VO及其對應(yīng)的View對象

領(lǐng)域驅(qū)動設(shè)計

領(lǐng)域驅(qū)動設(shè)計(DDD)對于安卓童鞋可能非常熟悉,有興趣的童鞋可以參考這篇文章腊嗡,本文不做過多講解刹枉,借用其描述介紹幾個名詞

VO(View Object):視圖對象屈呕,用于展示層,它的作用是把某個指定頁面(或組件)的所有數(shù)據(jù)封裝起來

DO(Domain Object):領(lǐng)域?qū)ο篌恚褪菑默F(xiàn)實世界中抽象出來的有形或無形的業(yè)務(wù)實體

PO(Persistent Object):持久化對象嗽桩,它跟持久層(通常是關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)結(jié)構(gòu)形成一一對應(yīng)的映射關(guān)系,如果持久層是關(guān)系型數(shù)據(jù)庫湿痢,那么扑庞,數(shù)據(jù)表中的每個字段(或若干個)就對應(yīng)PO的一個(或若干個)屬性

Domain:領(lǐng)域驅(qū)動層,是用戶與數(shù)據(jù)庫交互的核心中轉(zhuǎn)站臀规,控制用戶數(shù)據(jù)收集栅隐,控制請求轉(zhuǎn)向等

MVVM架構(gòu)中,ViewModel連接視圖View和數(shù)據(jù)業(yè)務(wù)Model層谨究,而Domain和Data數(shù)據(jù)持久層共同組成整個Model層泣棋。完整結(jié)構(gòu)如圖所示:


Model并不表示Model

MVVM架構(gòu)中的M外傅,并不表示Model對象俩檬,而是表示整個數(shù)據(jù)業(yè)務(wù)層碾盟,對應(yīng)DDD架構(gòu)中的Domain層以及數(shù)據(jù)Data層。業(yè)務(wù)開發(fā)中屈藐,一般考慮Api或者DB對象熙尉,極少考慮Domain層設(shè)計,也不會區(qū)分DO或者PO對象包归∏撸籠統(tǒng)定義Model ,將其傳遞給展示層ViewModel厦幅,久而久之慨飘,Model對象承載的信息越來越多,更有甚者缚态,在Model中處理業(yè)務(wù)邏輯堤瘤,導(dǎo)致項目維護(hù)成本增加,代碼中出現(xiàn)if..else的概率也會越來越大:

@interface?PersonModel?:?NSObject

@property?(nonatomic,?assign)?NSInteger?sex;

@property?(nonatomic,?readonly)?NSString?*sexDescription;

@end

@implementation?PersonModel

//?model中不應(yīng)該存在業(yè)務(wù)邏輯代碼

-?(NSString?*)sexDescription?{

returnself.sex?==?0???@"男":?@"女";

}

@end

當(dāng)然桥帆,Domain層并不是必須的慎皱,實際開發(fā)中,需要根據(jù)具體復(fù)雜度和需求來決定祈匙。比如只是純粹的請求展示界面,設(shè)計過多的層次結(jié)構(gòu)反而會增加項目的維護(hù)成本跪帝。同時些阅,Domain層不應(yīng)該存在任何狀態(tài)變量!

Data數(shù)據(jù)層

ViewModel負(fù)責(zé)展示層邏輯市埋,而Data層則對應(yīng)數(shù)據(jù)層邏輯缤谎,一般以Manager或者Service身份存在,數(shù)據(jù)來源主要包括Api坷澡、DB或者Cache等洋访。Data數(shù)據(jù)層操作對象主要為PO持久化對象谴餐,對象一旦創(chuàng)建,原則上不可修改

Data數(shù)據(jù)層具有獨立可測試性汁展,其不依賴視圖層而存在厌殉。切記不可在Data層操作任何視圖對象!

@implementation?PersonDBAccess

//?Data層不應(yīng)該存在任何視圖相關(guān)代碼

-?(NSArray?*)fetchPersonModels?{

[SVProgressHUD?showWithStatus:@"加載中器紧。楼眷。。"];

}

@end

MVVM奇葩說

文章到此掌腰,想必各位對MVVM架構(gòu)已經(jīng)有了大致了解张吉。對比安卓童鞋對MVP架構(gòu)的鐘愛,iOS童鞋也許更加青睞MVVM勺择,拌上ReactiveCocoa或者RxSwift,這道菜可以做的更加絢爛多彩扰藕!當(dāng)然芳撒,正如唐巧在文中所言:ReactiveCocoa 和 MVVM 不應(yīng)該被神化,我們需要保持的是一個擁抱變化的心芥备,以及理性分析的態(tài)度舌菜。在新技術(shù)的面前,不盲從袱瓮,也不守舊爱咬,一切的決策都應(yīng)該建立在認(rèn)真分析的基礎(chǔ)上,這樣才能應(yīng)對技術(shù)的變化燎斩!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栅表,一起剝皮案震驚了整個濱河市师枣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洗贰,老刑警劉巖拨脉,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玫膀,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機灵妨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門泌霍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來述召,“玉大人,你說我怎么就攤上這事藤为《嵝蹋” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵存淫,是天一觀的道長桅咆。 經(jīng)常有香客問我倾哺,道長刽脖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任却邓,我火速辦了婚禮院水,結(jié)果婚禮上檬某,老公的妹妹穿的比我還像新娘。我一直安慰自己恢恼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布牵署。 她就那樣靜靜地躺著喧半,像睡著了一般。 火紅的嫁衣襯著肌膚如雪取具。 梳的紋絲不亂的頭發(fā)上扁耐,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天做葵,我揣著相機與錄音,去河邊找鬼酿矢。 笑死瘫筐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肛捍。 我是一名探鬼主播之众,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缀蹄!你這毒婦竟也來了膘婶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脊岳,沒想到半個月后筛璧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夭谤,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡巫糙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年参淹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恳不。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡烟勋,死狀恐怖筐付,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓦戚,我是刑警寧澤较解,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站啡捶,受9級特大地震影響当编,放射性物質(zhì)發(fā)生泄漏徒溪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渠概。 院中可真熱鬧嫂拴,春花似錦筒狠、人聲如沸箱沦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寒跳。三九已至,卻和暖如春童太,著一層夾襖步出監(jiān)牢的瞬間书释,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工择膝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留检激,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓齿穗,卻偏偏與公主長得像窃页,于是被迫代替她去往敵國和親复濒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容