何為架構(gòu)?
- 軟件開發(fā)中的設(shè)計方案。
- 類與類之間的關(guān)系、模塊與模塊之間額關(guān)系、客戶端與服務(wù)端的關(guān)系。
經(jīng)常聽到的架構(gòu)名詞?
- MVC、MVP、MVVM、VIPER、CDD。
- 三層架構(gòu)、四層架構(gòu)。
MVC
Model-View-Controller
- Model:
模型對象封裝了應(yīng)用程序的數(shù)據(jù),并定義操控和處理該數(shù)據(jù)的邏輯和運(yùn)算。例如,模型對象可能是表示商品數(shù)據(jù) list。用戶在視圖層中所進(jìn)行的創(chuàng)建或修改數(shù)據(jù)的操作,通過控制器對象傳達(dá)出去,最終會創(chuàng)建或更新模型對象。模型對象更改時(例如通過網(wǎng)絡(luò)連接接收到新數(shù)據(jù)),它通知控制器對象,控制器對象更新相應(yīng)的視圖對象。 - View:
視圖對象是應(yīng)用程序中用戶可以看見的對象。視圖對象知道如何將自己繪制出來,可能對用戶的操作作出響應(yīng)。視圖對象的主要目的就是顯示來自應(yīng)用程序模型對象的數(shù)據(jù),并使該數(shù)據(jù)可被編輯。盡管如此,在 MVC 應(yīng)用程序中,視圖對象通常與模型對象分離。
在iOS應(yīng)用程序開發(fā)中,所有的控件、窗口等都繼承自 UIView,對應(yīng) MVC 中的 V。UIView 及其子類主要負(fù)責(zé) UI 的實(shí)現(xiàn),而 UIView 所產(chǎn)生的事件都可以采用委托的方式,交給 UIViewController 實(shí)現(xiàn)。 - Controller:
在應(yīng)用程序的一個或多個視圖對象和一個或多個模型對象之間,控制器對象充當(dāng)媒介??刂破鲗ο笠虼耸峭焦艿莱绦颍ㄟ^它,視圖對象了解模型對象的更改,反之亦然??刂破鲗ο筮€可以為應(yīng)用程序執(zhí)行設(shè)置和協(xié)調(diào)任務(wù),并管理其他對象的生命周期。
控制器對象解釋在視圖對象中進(jìn)行的用戶操作,并將新的或更改過的數(shù)據(jù)傳達(dá)給模型對象。模型對象更改時,一個控制器對象會將新的模型數(shù)據(jù)傳達(dá)給視圖對象,以便視圖對象可以顯示它。

MVC
- 優(yōu)點(diǎn):View、Model可以重復(fù)利用。
- 缺點(diǎn):Controller的代碼過于臃腫。
MVP
Model View Presenter(模型 視圖 協(xié)調(diào)器)
- Model:
數(shù)據(jù)對象,包含網(wǎng)絡(luò)請求,以及數(shù)據(jù) SQLite 的 CRUD(增加(Create)、讀取(Retrieve)、更新(Update)和刪除(Delete)) 操作(比如 iOS 平臺,一般以 FMDB 框架直接操作 sql,或者用 CoreData) 。一般可以將數(shù)據(jù)對象是否需要緩存設(shè)計成一個字段 isCache,或者針對整個項目設(shè)計一個開存儲關(guān),決定整個項目是否需要數(shù)據(jù)緩存。我們常見的新聞類 App,在離線的時候看到的數(shù)據(jù),都是做了緩存處理的。比如一些金融類的 App,實(shí)時性比較高,是不做緩存的。 - View:
就是 View 的一些封裝、重用。在一款精心設(shè)計過的 App 里面,應(yīng)該有很多 View 是可以封裝重用的。比如一些自己的 TableViewCell,自己設(shè)計的 Button,一些 View(包含一些子 View,UI 精心設(shè)計過,在項目里多處出現(xiàn)的)等等。 -
Presenter:
只是 Model 層和 View/ViewController層的一個橋梁。Presenter 層就不至于太臃腫,容易看懂。一些大的 App,或因為上線時間比較久了,經(jīng)歷過眾多程序員的修補(bǔ),或因前期并未做好架構(gòu),以至于打開一個類,幾千行的代碼,看著自己都暈。
MVP - 優(yōu)點(diǎn):
模型與視圖完全分離,我們可以修改視圖而不影響模型
可以更高效地使用模型,因為所有的交互都發(fā)生在一個地方——Presenter內(nèi)部
我們可以將一個Presener用于多個視圖,而不需要改變Presenter的邏輯。這個特性非常的有用,因為視圖的變化總是比模型的變化頻繁。
如果我們把邏輯放在Presenter中,那么我們就可以脫離用戶接口來測試這些邏輯(單元測試) - 缺點(diǎn):
由于對視圖的渲染放在了Presenter中,所以視圖和Persenter的交互會過于頻繁。
還有一點(diǎn)你需要明白,如果Presenter過多地渲染了視圖,往往會使得它與特定的視圖的聯(lián)系過于緊密。一旦視圖需要變更,那么 Presenter也需要變更了。比如說,原本用來呈現(xiàn)Html的Presenter現(xiàn)在也需要用于呈現(xiàn)Pdf了,那么視圖很有可能也需要變更。
MVVM
View、View Model、Model這三部分之間的相互解耦。
- Model:
與業(yè)務(wù)和驗證邏輯有關(guān)的域模型,都可以認(rèn)為是MVVM中的Model。比如:業(yè)務(wù)對象,數(shù)據(jù)傳輸對象(DTOs),實(shí)體,代理對象等等都可以認(rèn)為是Model。
這里的Model與MVC中的Model一樣。 - View:
View負(fù)責(zé)定義頁面結(jié)構(gòu),布局用戶在屏幕上看到的界面。在iOS開發(fā)中,View一般是程序中的一個頁面。一個View也可以是父View的一部分。
每個View都有自己的View Model,或者它從父View中繼承了View Model。View通常是通過通過View Model的綁定,或者調(diào)用View Model中的方法來獲取數(shù)據(jù)。在運(yùn)行的時候,UI控件要響應(yīng)View Model拋出通知事件,來更新UI。
為了響應(yīng)UI上的交互,需要在View Model中實(shí)現(xiàn)相應(yīng)的代碼。比如一個按鈕被點(diǎn)擊。需要將這個按鈕點(diǎn)擊事件綁定到View Model中去。然后在View Model中寫代碼處理用戶的交互。
在iOS開發(fā)中View和ViewController都是屬于View這部分。 - View Model:
View Model扮演著View和Model的中介角色,它負(fù)責(zé)處理視圖邏輯和數(shù)據(jù)轉(zhuǎn)化。一般來說View Model通過調(diào)用Model的方法來和Model進(jìn)行交互。View Model隨后將從Model中獲取的數(shù)據(jù)以一種view容易使用的格式提供給View。View Model負(fù)責(zé)UI交互的響應(yīng)代碼實(shí)現(xiàn)。例如:當(dāng)用戶點(diǎn)擊了一個按鈕在UI中,這個動作會使得View Model中相應(yīng)代碼被執(zhí)行。View Model也負(fù)責(zé)控制視圖的顯示邏輯,比如修改UI指示操作正在進(jìn)行。

MVVM
- 優(yōu)點(diǎn):
方便測試 便于代碼的移植。
兼容MVC。 - 缺點(diǎn):
類會增多,ViewModel會越來越龐大,調(diào)用復(fù)雜度增加。
VIPER
- View(視圖)
提供完整的視圖,負(fù)責(zé)視圖的組合、布局、更新
向Presenter提供更新視圖的接口
將View相關(guān)的事件發(fā)送給Presenter - Presenter(展示器)
接收并處理來自View的事件
向Interactor請求調(diào)用業(yè)務(wù)邏輯
向Interactor提供View中的數(shù)據(jù)
接收并處理來自Interactor的數(shù)據(jù)回調(diào)事件
通知View進(jìn)行更新操作
通過Router跳轉(zhuǎn)到其他View - Router(路由)
提供View之間的跳轉(zhuǎn)功能,減少了模塊間的耦合
初始化VIPER的各個模塊 - Interactor(交互器)
維護(hù)主要的業(yè)務(wù)邏輯功能,向Presenter提供現(xiàn)有的業(yè)務(wù)用例
維護(hù)、獲取、更新Entity
當(dāng)有業(yè)務(wù)相關(guān)的事件發(fā)生時,處理事件,并通知Presenter - Entity(實(shí)體)
和Model一樣的數(shù)據(jù)模型

VIPER
- 優(yōu)點(diǎn):
可測試性好。UI測試和業(yè)務(wù)邏輯測試可以各自單獨(dú)進(jìn)行。
易于迭代。各部分遵循單一職責(zé),可以很明確地知道新的代碼應(yīng)該放在哪里。
隔離程度高,耦合程度低。一個模塊的代碼不容易影響到另一個模塊。
易于團(tuán)隊合作。各部分分工明確,團(tuán)隊合作時易于統(tǒng)一代碼風(fēng)格,可以快速接手別人的代碼。 - 缺點(diǎn):
一個模塊內(nèi)的類數(shù)量增大,代碼量增大,在層與層之間需要花更多時間設(shè)計接口。
模塊的初始化較為復(fù)雜,打開一個新的界面需要生成View、Presenter、Interactor,并且設(shè)置互相之間的依賴關(guān)系。而iOS中缺少這種設(shè)置復(fù)雜初始化的原生方式。
