在iOS專案中引入MVVM

2021-06-27 12:57:10 字數 3464 閱讀 4903

本文翻譯自:

mvc?還有另外乙個解釋:massive view controller,翻譯過來就是一大堆的view controller的意思。有的時候真的時有這種感覺,view controller太多了。尤其在乙個人晚上加班改bug的時候,感覺更明顯。於是,你會恨不得全部推倒重來算了!

從架構的角度考慮,也許mvc的乙個衍生架構mvvm更加的合適。這裡就不討論mvvm的前世今生了。園子裡的各位.net達人從很久以前就已在wpf上玩這個東西了。先看一下ios的mvc是什麼樣的,然後一步一步的進入mvvm。ios的mvc:

這是乙個典型的mvc架構。models代表資料,views代表的時使用者介面,view controllers在中間協調。仔細一想你會發現,雖然view和view controller是兩個完全不同的東西,但是他們卻緊密結合。什麼時候乙個view可以和不同的view controller結合使用,或者乙個view controller可以和不同的view結合使用。所以,這個架構其實是這樣的:

這樣就跟準確的描述了mvc架構下的**是怎麼寫的。但是,這還沒有反應出來ios開發中大量增加的view controller。在典型的mvc應用中,很多的邏輯處理放在view controller中。有些確實是需要放在view controller中的。但是還有很大一部分式「展示邏輯(presentation logic)」。這是乙個mvvm的術語,指的是那些把model裡d的資料轉換成view中可以顯示的形式的過程。比如,把乙個nsdata轉換成有一定格式的nsstring就是這麼乙個過程。

上面的圖都少了一部分內容。缺少了的就是那部分「展示邏輯」。這一部分抽象出來之後就可以叫做「view model」。這一部分在view、view controller和model之間。

看起來更合理了把。這附圖準確的描述了什麼是mvvm,乙個增強版的mvc。這裡,我們可以正式的把view和controller連線起來。並把展示邏輯從view controller中挪出去,形成乙個新的物件:view model。mvvm聽起來複雜,其實就是乙個穿了件新衣的mvc。本質上和mvc是一樣的。

現在您應該清楚什麼是mvvm了。那麼,為什麼要用這個東西呢?因為,使用這個架構編寫**可以減少view controller的複雜度,並且展示的邏輯也更容易測試。下面就通過**展示一下mvvm的這兩點好處。

有三點一定在文中強調:

mvvm和您現有的mvc架構是相容的。

mvvm可以和綁定型的架構很好共存。

如前文所述,mvvm就是乙個加強版的mvc。所以很容易看到這個模式如何和之前的mvc架構共存。我們先建立乙個簡單的person model和對應的view controller。

//

//mvvm

////

created by bruce lee on 9/12/14.

////

qq群:58099570

//import uikit

class person

}

現在假設我們有乙個view controller叫做personviewcontroller,在viewdidload中要用model person來設定一些label的值:

override func viewdidload() 

else

var dateformatter = nsdateformatter()

dateformatter.dateformat = "

eeee mmmm d, yyyy

" self.birthdatelabel.text = dateformatter.stringfromdate(self.model.birthdate!)

}

這些都是最常規的mvc**的寫法。下面看看如何寫view model。

import uikit

class personviewmodel

else

var dateformatter = nsdateformatter()

dateformatter.dateformat = "

eeee mmmm d, yyyy

" self.birthdatetext = dateformatter.stringfromdate(self.person.birthdate!)}}

這樣,顯示邏輯已經從viewdidload方法中遷移了出去。現在viewdidload方法就顯得輕量了很多。

override func viewdidload()
你會看到,並不需要對mvc架構做多大的修改。幾乎只是原來的**稍作移動。完全和mvc相容,減少了view controller的重量,而且變得更加容易測試。

下面說說可測試。view controller的難以測試簡直是出了名的。在mvvm中,**很大一部分都移到了view model中。並且view model都是很容易測試的。如:

var person: person!

override func setup()

func testusersalutation()

func testnosalutation()

func testbirthdateformat()

如果不是把**移到了view model中,測試的時候就不得不初始化乙個view controller,當然還有view controller裡的一堆view。然後對比的時這些view(上例提到的時label)的某些屬性的值。這樣不僅是非常的不方便、不直接,而且還會形成一種非常脆弱的測試:因為,view controller的試圖層次根本就不能有任何的變動,一旦變動測試即告失敗!或者測試根本就編譯不過。使用mvvm對於測試的益處是顯而易見的。在上例中還是比較簡單的邏輯。如果換做其他的產品環境的複雜的顯示邏輯的話,這種易於測試的好處會更加明顯。

注意到,上面使用到的例子都是比較簡單的。沒什麼需要修改的屬性。可以直接使用初始值初始化物件。對於有修改的model。我們需要用到某中繫結機制。這樣在model的某些值修改以後才能保證基於這個model的view model的值也跟著改變。更深一步,model值修改之後,view呼叫的view model的值也能跟著修改。也就是,乙個對於model的修改,和model相關的view model和view的值都能同步的更新。

在osx上,可以使用cocoa bindings。但是ios上沒有這個奢侈品。但是key-value observation完全可以勝任。只是在很多屬性的時候會增加**量。也可以使用reactivecocoa。當然這只是乙個選擇。乙個不錯的繫結框架,會使mvvm好上加好。

在mingw專案中引入googletest

之前的文章,介紹了如何在windows下使用 mingw 和 eclipse 來搭建 c 的開發環境。這篇文章在此基礎上,介紹如何在專案中引入著名的單元測試框架 googletest。有關於單元測試和 googletest 的測試和可以參考這兩篇文章 單元測試,googletest 簡單的說,單元測...

在Java專案中引入日誌

日誌 log 主要用來記錄系統執行中一些重要操作資訊 便於監視系統運 況,幫助使用者提前發現和避開可能出現的問題,或者出現問題後根據日誌找到原因 日誌分類 sql日誌 異常日誌 業務日誌 可以自己寫個日誌記錄的小工具 log4j是乙個非常優秀的開源日誌框架 控制日誌的輸出級別 控制日誌資訊輸送的目的...

專案中引入字型

font face html,body蘋方提供了六個字重,font family 定義如下 蘋方 簡 常規體 font family pingfangsc regular,sans serif 蘋方 簡 極細體 font family pingfangsc ultralight,sans serif...