說說視圖層架構

前言

最近在思考關於iOS視圖架構的一些東西,因而開始糾結MVC、MVVM等架構。因爲項目裏原來的代碼比較亂,日積月累,維護的人也換了又換,能夠說到了十分臃腫難以維護的地步。因此借某個機會得以對其進行從新設計。項目裏的業務邏輯比較多,也比較亂。因此必須把架構作好,以方便後期的維護。html

說回視圖層架構,這陣子參考了不少資料,包括MVC、MVVM等,每一個人的說法都不徹底一致。只有一種解釋,那就是架構模式不是一層不變的,而是在不斷髮展的,正如項目也在發展,項目的代碼也在重構。因此,這篇文章談到的不必定是這些架構最真實的概念,而是我對它們的理解。中間的理解也可能會存在某些問題,歡迎提出來而後一塊兒完善。ios

同時,這篇文章所說的架構都是針對iOS的視圖架構,而對於Android和Web等,雖然原理類似,但在實際開發過程當中卻可能出入很大,甚至適用狀況都是不一樣的。因此還須要其餘相關人員來補充。編程

 

View層架構

說到架構固然少不了MVC,後續發展出了MVP,以及升級版的MVCS、MVVM等。這些架構其實都是想通的,但在學習的過程當中老是感受有不少沒法理清的地方,包括它們最原始的概念、它們的發展、以及適用狀況等。架構

MVC

MVC把架構劃分爲三個部分,分別是Model、View和Controller。能夠說,三層架構是一切視圖層架構的基礎,其餘的模式都是從三層架構發展而來的。mvc

  • View:主要負責視圖的顯示mvvm

  • Model:主要負責數據的管理學習

  • Controller:協調View和Model測試

MVC是一個比較古老的模式,咱們先來看看MVC的基本結構。架構設計

傳統的MVC結構圖

從上圖咱們能夠看到這樣的關係鏈:設計

  • View向Controller傳遞交互信息

  • Controller通知Model改變數據

  • View從Model獲取數據顯示到視圖中,Model更新數據後通知View更新視圖

事實上,這是最傳統的MVC結構。在這種結構下,View和Model互相持有,甚至View和Controller以及Controller和Model的關係都是千絲萬縷,很是不利於維護。因此,後來的MVC發展出了新的結構。

新的MVC結構圖

如今來看看新的關係鏈:

  • View向Controller傳遞交互信息

  • Controller通知Model改變數據

  • Model更新數據後通知Controller改變數據

  • Controller得知數據改變後通知View更新視圖

能夠看到,演變出來的新MVC去掉了View和Model之間的聯繫,讓View只與Controller交流,而Model也只與Controller交流。而這樣的結構也稱之爲重量級視圖控制器結構,除了視圖部分和數據部分,其他的都交給Controller,後面會繼續講到。

因此,如今所說的MVC,基本都是指新的視圖控制器。View和Model之間的解耦有利於項目的開發,讓負責不一樣模塊的開發人員不用擔憂本身的改動影響到別人的代碼。

MVP

MVP是從MVC發展來的,它基本與新的MVC一致,只是詳細定義了MVC中各個部分的職能以及它們的交流方式,並讓視圖和控制器之間經過接口交流。

在MVP裏,Controller的概念換成了Presenter,主要職能是用來展現界面,但其實和Controller沒有太大的差異。

MVP結構圖

MVP最重要的就是在View和Presenter之間新增了一層IView的接口,View和Presenter經過IView來交流。以前說到新的MVC中View和Model進行了解耦,而在MVP中,View和Presenter進一步解耦。讓視圖只作視圖的功能,而控制器只作控制器的功能,二者經過接口交流,互不影響。

可見,MVP和MVC仍是十分類似的。

MVCS

MVCS是從MVC發展而來的,MVCS也不是什麼高深莫測的架構,只是把Model中的數據存儲部分Store分離開來。Model負責數據的管理,而Store負責數據的存儲。

MVVM

MVVM,雖然它的名稱裏沒有C,但並不表示它就沒有Controller。相反,因爲MVVM裏的Controller和View聯繫緊密,已經融爲一體了。因此,能夠把MVVM理解爲MVCVM,或者把MVVM裏的V理解爲VC,即View和Controller。

MVVM結構圖

MVVM裏的VM指的是ViewModel,它把MVC中本來屬於Controller的業務邏輯部分抽離出來造成了ViewModel。這樣,Controller裏只剩下和View交互相關的部分,而業務邏輯這種與視圖顯示、視圖交互無關的部分則獨立爲ViewModel。

因此,Controller和View結合到一塊兒,和ViewModel互相交流,而ViewModel再和Model交流。其實這樣的方式和MVC是十分類似的,一樣是視圖和業務邏輯交流,業務邏輯則和數據交流。

MVVM還有一個重要的概念,就是數據綁定。數據綁定使得View和ViewModel的交流更加方便,至關於把視圖的數據綁定到業務邏輯中,任何一方改變都會影響到另外一方的改變。固然,數據綁定並非必須的,使用通知、觀察者模式、代理等均可以實現MVVM。

 

胖與廋

胖與瘦,指的是一個層是否臃腫,是否包含了不少邏輯、不少代碼。而比較有爭議的就是胖Model和瘦Model,由於胖Model意味着瘦Controller,而瘦Model則意味着胖Controller。

瘦Model,是MVC的一個特徵。由於Model只負責了數據管理部分,若是Model大了,能夠分出Store,但再怎麼分,仍是數據管理。此時的Controller,既負責了View層的交互控制,也包含了業務邏輯(業務邏輯中分爲強業務邏輯和弱業務邏輯)。如此,Controller天然要負責不少東西。

而胖Model,則要求把Controller的弱業務邏輯移到Model中,爲Controller減負。這樣,Controller則負責和View的交互以及強業務邏輯。

其實,胖與瘦的Model,只是決定了弱業務邏輯的位置。瘦Model的弱業務邏輯放在Controller中,而胖Model的弱業務邏輯放在Model中。

那咱們應該提倡哪種呢?

事實上,弱業務邏輯應該儘量的獨立出去,並使用胖Model方式。緣由有三。

  • 弱業務邏輯應該從Controller分離出去,由於等到Controller臃腫的時候再想分離的話會比較困難。

  • 弱業務邏輯應該放到Model中,由於Model封裝了數據的處理,弱業務邏輯屬於數據處理部分。

  • 弱業務邏輯包含到Model並保持獨立,便於Model的維護,也便於弱業務邏輯的測試。

因此,當一個邏輯你不知道寫到哪一個層的時候,寫到Model層,這樣後期想要重構的話也會十分方便。

 

架構的關鍵

架構的關鍵只有一個字,那就是「拆」。

其實架構都是在不斷髮展的,每一個架構都是在以前架構的基礎上發展而來,從上面的架構來看,架構之間也是類似的,必然包含View、Model和Controller。

A拆爲MV

A表示一個應用。一開始,若是應用很小,你可能會想把全部代碼寫到一塊兒。而項目大了,爲了便於管理,天然要把它拆爲Model和View,由於你知道Model是不變,而View老是會改變。

V拆爲VC -> MVC

而當View多了以後,或者一個View裏面有太多交互邏輯的時候,你就會考慮把View裏的Controller部分拆開來。由於View有時候是不變的,但交互方式常常會發生改變。這樣的拆法就是MVC的雛形。至於各個層之間的交流方式如何,則任你定義。

M拆爲MS -> MVCS

Model層也會變大,那天然也得把不變的部分拆了,因而把數據存儲部分拆爲Store。這樣就成了MVCS。

C拆爲CVM -> MVVM

Controller變大以後,把它的業務邏輯和交互邏輯拆開,讓Controller只負責交互,而業務邏輯封裝到ViewModel裏。也就成了MVVM。

M拆爲VM和S -> MVVMS

若是MVVM裏以爲M太大了,天然能夠和MVCS同樣把Model拆出Store來,起名爲MVVMS。

小結

因此,只要你須要,你能夠把MVC的任意一層拆了,拆出一層或兩層均可以,只要以爲有須要就能夠拆。因此,其實並無所謂的太多架構,其餘架構都是人們爲了拆MVC而起的新名字。

 

原則

解耦

解耦是必須的,任何一個層之間耦合太大,都不便於維護。試想一下,Controller裏面對視圖及子視圖任意調用,同時任意調用Model的屬性方法,而View層和Model層互相持有,有朝一日想要修改視圖,那但是吐血的心都有了。

面向接口

面向接口是重要的,可是是可選的。面向接口編程有利於開發和維護,但必須接口明確。結構良好的項目,針對常常發生變化的模塊,能夠創建接口,這樣就避免了每次改變都須要修改代碼。但若是項目不大,項目不規範的話,也不太好定義接口。而有時候某些模塊不怎麼變化,定義接口也會增長不少工做。

因此,若是要定義接口,就應該採起一套規範,並儘早定義。

單一原則

把同一類邏輯放到同一個模塊,不一樣邏輯不要放到同一個模塊。若是是處理圖片的就寫到圖片的模塊裏,若是是處理字符串的就寫到字符串裏,而不要由於它們都是解決相近的問題或者由於它們代碼很少就寫到一個文件裏,這樣後期會增長不少維護成本。

 

總結

這一次的學習也讓我漸漸地理清了代碼的架構,爲後面的代碼架構作好基礎。

對於任何一個問題,最好都必須進行系統性的學習。可是如今網上可能沒有太多系統性的資料,書本的知識也很容易過期。這就須要咱們快速地從網上尋找大量的資料,分門別類地學習,並儘快總結。總結了,才能從中獲取真正的知識。

 

參考資料

相關文章
相關標籤/搜索