Software Design Architecture, MVVM(R) — update

哈囉,大家好!

今天這篇文章想來跟大家說說 MVVM ,也許之後會把 MVX 家族的都補齊,但是目前正在熟悉 MVVM,所以就先跟大家聊聊這個主題。


在我繼續往下走之前,預期大家對於 MVC 都有基本概念,寫不出來沒關係,至少知道彼此之間在幹嘛。如果還是有點障礙,建議可以先看看 Standford CS193P 的課程,大概前 15 分鐘就把 MVC 講得很清楚了,看一下麻~~


好的,如果你對 MVC 已經有基礎的了解之後,我們先來看看對於 MVVM 中各項的定義吧

Model : 跟 MVC 中的 Model 一樣,負責處理請求與商業邏輯等等。

View : 這邊的 View 可能就不太相同,MVC 當中的 View 僅有 UIView 就這樣,但是在 MVC 之外的其他設計架構 (MVP, MVVM, VIPER) 當中的 View 除了 View 還包含了 View Controller,但是他們就只做把資料擺進去顯示,其他邏輯程式碼都沒有在其中執行。因此常常會在其他文章中看到有人稱做 Passive View / Dumb View,因為他們很笨,只會顯示由 View Model 提供的資料。

View Model: 這邊的 View Model 則必須負責儲存 View 所要用來顯示的資料。所有 View 要做顯示的資料,都應該要透過 Method / Property 來跟 View Model 做取得。

實作 TableView 會有 RowsInSection / CellForRowAt 這兩個方法必須實作,這時我們就不能把資料放在 View Controller 直接去做存取,而是透過方法來跟 View Model 取得,存放在 View Model 裡面的資料筆數,以及所要顯示的資料內容。

我這邊補充說明一下 MVVMR 的 R,其實 MVVMR 跟 MVVM 的概念大抵相同,只是我們常常在程式碼內生成下一個 View Controller 並且透過 Navigation Controller Push / Pop 到下一個畫面,但是這樣做就會使程式碼的相依性提高。如果為了程式碼的彈性與低耦合度的設計,應該要把生成 View Controller 的動作拿到外部來實作,而不應該讓一個 View Controller 擁有下一個 View Controller。

這時問題就來了,誰該來做這件事? View? ViewModel? Model?

Router 這時就派上用場了,我們可以在 Router 中依據邏輯判斷,決定螢幕接下來往哪走,然後在 Router 中把畫面生成,並且使用 Navigation Controller.Push 前往下一個畫面。

如此就可以降低耦合度,而且也不會讓你們的 View Controller 彼此間互相擁有。


總結

大家在撰寫程式碼的時候,只要記得時時問問自己,這個方法寫在這裡對嗎?現在在寫的這個是 Model? View Model? 還是 View? 有沒有跨越職責的疑慮?盡可能的符合單一職責原則(Single Response Principle),就可以寫出具備彈性且低耦合度的程式碼了。


下方是我自己寫的一個 Objective-C 的範例專案,別問我為什麼不是 Swift,如果你想看我寫 Swift 就留言讓我知道吧!

當中也許沒有 MVVMR 的 100% 徹底,但是也有 87% 像了,大家可以先看看內容,如果有任何問題或是文章內有錯誤的地方,歡迎留言讓我知道。

圖片皆來自 google search ,如果有侵權的地方,還請讓我知道,會盡快拿掉,謝謝!


最近播了一點時間,完成了 swift 的版本,也順便研究了一下 MVP, 其實我覺得兩者差距不多,如果真的硬要說差別的話, MVVM 可能會用上 data binding 的做法來完成資料更新後 UI 接著刷新,可以參考一下我用 MVVM 寫的 randomuser, 可能不是 100% 的完美,但希望你能從中體會到 MVVM 的精髓。

https://github.com/nick1ee/MVVM_RandomUser