說說視圖層架構

jopen 9年前發布 | 33K 次閱讀 架構 軟件架構

前言

最近在思考關于iOS視圖架構的一些東西,于是開始糾結MVC、MVVM等架構。由于項目里原來的代碼比較亂,日積月累,維護的人也換了又換,可 以說到了十分臃腫難以維護的地步。所以借某個機會得以對其進行重新設計。項目里的業務邏輯比較多,也比較亂。所以必須把架構做好,以方便后期的維護。

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

同時,這篇文章所說的架構都是針對iOS的視圖架構,而對于Android和Web等,雖然原理相似,但在實際開發過程中卻可能出入很大,甚至適用情況都是不同的。所以還需要其他相關人員來補充。

View層架構

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

MVC

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

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

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

  • Controller:協調View和Model

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

說說視圖層架構

從上圖我們可以看到這樣的關系鏈:

  • View向Controller傳遞交互信息

  • Controller通知Model改變數據

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

事實上,這是最傳統的MVC結構。在這種結構下,View和Model互相持有,甚至View和Controller以及Controller和Model的關系都是千絲萬縷,非常不利于維護。所以,后來的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最重要的就是在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里的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層互相持有,有朝一日想要修改視圖,那可是吐血的心都有了。

面向接口

面向接口是重要的,但是是可選的。面向接口編程有利于開發和維護,但必須接口明確。結構良好的項目,針對經常發生變化的模塊,可以建立接口,這樣 就避免了每次改變都需要修改代碼。但如果項目不大,項目不規范的話,也不太好定義接口。而有時候某些模塊不怎么變化,定義接口也會增加很多工作。

所以,如果要定義接口,就應該采取一套規范,并盡早定義。

單一原則

把同一類邏輯放到同一個模塊,不同邏輯不要放到同一個模塊。如果是處理圖片的就寫到圖片的模塊里,如果是處理字符串的就寫到字符串里,而不要因為它們都是解決相近的問題或者因為它們代碼不多就寫到一個文件里,這樣后期會增加很多維護成本。

總結

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

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

參考資料

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!