聲明:本文不少部分是對王巍App 架構一書的學習筆記,若有侵權,請告知程序員
構建 — 誰負責構建 model 和 view,以及將二者鏈接起來? 更新 model — 如何處理 view action? 改變 view — 如何將 model 的數據應用到 view 上去? view state — 如何處理導航和其餘一些 model state 之外的狀態?編程
「View 層和 model 層須要交流。因此,二者之間須要存在鏈接。假設 view 層和 model 層是被清晰地分開,並且不存在沒法解耦的聯結的話,二者之間的通信就須要一些形式的翻譯:」 緩存
「當一個 view action 被送到 model 層時,它會被轉變爲model action (或者說,讓 model 對象執行一個 action 或者進行更新的命令)。這種命令也被叫作一個消息 (特別在當 model 是被 reducer 改變時,咱們會這麼稱呼它)。將 view action 轉變爲 model action 的操做,以及路徑上的其餘邏輯被叫作交互邏輯。」架構
「當 view 依賴於 model 數據時,通知會觸發一個 view 變動,來更改 view 層中的內容。這些通知能夠以多種形式存在:Foundation 中的 Notification,代理,回調,或者是其餘機制,都是能夠的。將 model 通知和數據轉變爲 view 更改的操做,以及路徑上的其餘邏輯被叫作表現邏輯。」app
「MVC 的核心思想是,controller 層負責將 model 層和 view 層撮合到一塊兒工做。Controller 對另外兩層進行構建和配置,並對 model 對象和 view 對象之間的雙向通信進行協調。因此,在一個 MVC app 中,controller 層是做爲核心來參與造成 app 的反饋迴路的:」框架
「圖中的虛線部分表明運行時的引用,view 層和 model 層都不會直接在代碼中引用 controller。實線部分表明編譯期間的引用,controller 實例知道本身所鏈接的 view 和 model 對象的接口」工具
MVC 中有兩個最多見的問題
學習
MVC構建
測試
「MVVM 構建的方式和 MVC 的模式很類似:controller 層充分了解程序的結構,它使用這些認知來對全部部件進行構建和鏈接。 MVVM 與 MVC 最大的區別可能在於 view-model 中對響應式編程的使用了,它被用來描述一系列的轉換和依賴關係。經過使用響應式編程來清晰地描述 model 對象與顯示值之間的關係,爲咱們從整體上理解應用中的依賴關係提供了重要的指導。 具體主要有三個不一樣:翻譯
「MVVM 一般要求 controller 必須很是簡單 (甚至簡單到無需考慮)。另外,controller 必須儘量地使用庫提供的綁定方法。在這樣的規則的保證下,理想狀況中咱們就不須要測試 controller 了,由於它沒有包含咱們本身的任何邏輯。究竟應該在 controller 中留存多少邏輯,根本上來講是掌握在程序員手上的。」
「MVVM 經過將 model 觀察的代碼以及其餘顯示和交互邏輯移動到圍繞着數據流構建的隔離的類中,解決了 MVC controller 裏不規則的狀態交互所帶來的有關問題。由於這是 MVC 中最顯著的問題,並且會隨着 Cocoa controller 的增大而惡化,這個變化在很大程度上緩解了 MVC 中 controller 肥大的問題。可是還有其餘一些因素會使得 controller (以及 view-model) 變大,因此爲了可持續發展,重構依然仍是有須要的」
MVVM的構建
關於view-model
實現狀態恢復數據 在狀態恢復的方法上,MVVM 中爲各個 controller 所存儲的數據來源於 view-model,而非像 MVC 那樣來源於 controller 自己,除此以外,二者所使用的策略大抵相同。
View-model 雖然名字裏既有 view 又有 model,可是它所扮演的實際上是徹徹底底的相似 controller 的角色。
View-model 從 view controller 和 view 中獨立出來,也能夠被單獨測試。一樣,view controller 也再也不擁有內部的 view state,這些狀態也被移動到了 view-model 中。在 MVC 中 view controller 的雙重角色 (既做爲 view 層級的一部分,又負責協調 view 和 model 之間的交互),減小到了單一角色 (view controller 僅僅只是 view 層級的一部分)。
「View-model 在編譯期間不包含對 view 或者 controller 的引用。它暴露出一系列屬性,用來描述每一個 view 在顯示時應有的值。把一系列變換運用到底層的 model 對象後,就能獲得這些最終能夠直接設置到 view 上的值。實際將這些值設置到 view 上的工做,則由預先創建的綁定來完成,綁定會保證當這些顯示值發生變化時,把它設定到對應的 view 上去。響應式編程是用來表達這類聲明和變換關係的很好的工具,因此它天生就適合 (雖然說不是嚴格必要) 被用來處理 view-model。在不少時候,整個 view-model 均可以用響應式編程綁定的方式,以聲明式的形式進行表達。
「在理論上,由於 view-model 不包含對 view 層的引用,因此它是獨立於 app 框架的,這讓對於 view-model 的測試也能夠獨立於 app 框架。」
「在理論上,由於 view-model 不包含對 view 層的引用,因此它是獨立於 app 框架的,這讓對於 view-model 的測試也能夠獨立於 app 框架。
因爲 view-model 是和場景耦合的,咱們還須要一個可以在場景間切換時提供邏輯的對象。在 MVVM-C 中,這個對象叫作協調器 (coordinator)。協調器持有對 model 層的引用,而且瞭解 view controller 樹的結構,這樣,它可以爲每一個場景的 view-model 提供所須要的 model 對象。」
和 MVC 不一樣,MVVM-C 中的 view controller 歷來都不會直接引用其餘的 view controller (因此,也不會引用其餘的 view-model)。View controller 經過 delegate 的機制,將 view action 的信息告訴協調器。協調器據此顯示新的 view controller 並設置它們的 model 數據。換句話說,view controller 的層級是由協調器進行管理的,而不是由 view controller 來決定的。若是咱們忽略掉協調器,那麼這張圖表就很像 MVC 了,只不過在 view controller 和 model 之間加入了一個階段。MVVM 將以前在 view controller 中的大部分工做轉移到了 view-model 中,可是要注意,view-model 並不會在編譯時擁有對 view controller 的引用。
「初步印象來講,由於 MVVM-C 加入了額外的一層來進行管理,看起來是比 Cocoa MVC 模式更加複雜。不過,在實現的層級,若是你可以始終如一地貫徹這個模式,代碼會變得更簡單一些。啊,這裏說的簡單並不意味着容易,只有當你對常見的響應式代碼變形熟悉之後,纔不會對書寫代碼感到無從下手,纔不會對調試問題感到懊惱沮喪。不過,從使人高興的一面來講,精心設計的數據管道一般不容易產生錯誤,在長期來看維護也更容易一些。」
「iOS 中的協調器是一種頗有用的模式,由於管理 view controller 層級是一件很是重要的事情。協調器在本質上並無和 MVVM 綁定,它也能被使用在 MVC 或者其餘模式上。」
協調器爲每一個 controller 的 view-model 設置初始的 model 對象。 View-model 將設定值和其餘 model 數據及觀察量進行合併。 View-model 將數據變形爲 view 所須要的精確的格式。 Controller 將準備好的值綁定到各個 view 上去。
對於Controller層過於臃腫的問題,MVP模式則能較好地解決這個問題——既然UIViewController和UIView是耦合的,索性把這二者都歸爲View層,業務邏輯則獨立存在於Presenter層,Model層保持不變。下圖比較清除得展現了MVP模式的結構
「model 適配器 - view 綁定器 (ModelAdapter-ViewBinder, MAVB)」
Elm 架構 (TEA)、VIPER、Riblets
「響應式編程是一種用來交流變動的工具,不過和通知或者 KVO 不一樣的是,它專一於在源和目標之間進行變形,讓邏輯能夠在部件之間傳輸信息的同時得以表達。」 「響應式編程是一種用來描述數據源和數據消費端之間數據流動的模式」 「數據變形的部分是響應式編程所能帶來的最大優點,但同時它也是學習曲線最爲陡峭的部分。」