本文翻譯自:
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。
//現在假設我們有乙個view controller叫做personviewcontroller,在viewdidload中要用model person來設定一些label的值://mvvm
////
created by bruce lee on 9/12/14.
////
qq群:58099570
//import uikit
class person
}
override func viewdidload()這些都是最常規的mvc**的寫法。下面看看如何寫view model。else
var dateformatter = nsdateformatter()
dateformatter.dateformat = "
eeee mmmm d, yyyy
" self.birthdatelabel.text = dateformatter.stringfromdate(self.model.birthdate!)
}
import uikit這樣,顯示邏輯已經從viewdidload方法中遷移了出去。現在viewdidload方法就顯得輕量了很多。class personviewmodel
else
var dateformatter = nsdateformatter()
dateformatter.dateformat = "
eeee mmmm d, yyyy
" self.birthdatetext = dateformatter.stringfromdate(self.person.birthdate!)}}
override func viewdidload()你會看到,並不需要對mvc架構做多大的修改。幾乎只是原來的**稍作移動。完全和mvc相容,減少了view controller的重量,而且變得更加容易測試。
下面說說可測試。view controller的難以測試簡直是出了名的。在mvvm中,**很大一部分都移到了view model中。並且view model都是很容易測試的。如:
var person: person!如果不是把**移到了view model中,測試的時候就不得不初始化乙個view controller,當然還有view controller裡的一堆view。然後對比的時這些view(上例提到的時label)的某些屬性的值。這樣不僅是非常的不方便、不直接,而且還會形成一種非常脆弱的測試:因為,view controller的試圖層次根本就不能有任何的變動,一旦變動測試即告失敗!或者測試根本就編譯不過。使用mvvm對於測試的益處是顯而易見的。在上例中還是比較簡單的邏輯。如果換做其他的產品環境的複雜的顯示邏輯的話,這種易於測試的好處會更加明顯。override func setup()
func testusersalutation()
func testnosalutation()
func testbirthdateformat()
注意到,上面使用到的例子都是比較簡單的。沒什麼需要修改的屬性。可以直接使用初始值初始化物件。對於有修改的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...