你的系統是MVC pattern還是MVC anti-pattern?

MVC是一種軟體架構模式,通常也是大多數程式設計新手第一個接觸的架構模式,因此也往往流於一種被濫用的名詞,許多程式設計師常把「我的系統是採MVC架構設計的」這樣的話掛在嘴邊:,又或者找了一個open source framework,就以為follow他們的設計就是MVC了。

MVC模式(Model-View-Controller pattern)

MVC模式的詳細介紹,可以參考維基百科:

https://en.wikipedia.org/wiki/Model–view–controller

其目的是為了使程式重複使用(reuse)、去耦合(de-coupling)、易維護性(maintainability)、清晰(clear)、 平行開發(parallel development)

因為MVC並沒有一個標準的定義,所以我們不管follow哪個定義,要謹記將重點放在“如何使用MVC達到上述的目的”,如此便容易釐清程式中的anti-pattern,並加以改善。

MVC之間是如何互動?角色分工?

  • Model:
    強調封裝(encapsulation),能根據problem domain描述應用程式的行為,例如會員資料的model、商品資料的model、物聯網裝置的model,它直接管理應用程式的資料、邏輯和規則,且在設計時必須與使用者介面無關,不依賴controller。model決定資料可以如何被操作?例如新增會員資料、刪除會員資料,以及這些操作只能有哪些角色執行等等。
    model設計的重點是要如何modeling?將其抽象化,成為一個domain或subject,讓需要的controller去使用它。
    model依據controller的要求,存取指定的資料,至於資料內容該如何呈現則交由view決定。
  • View:
    可以是任何輸出表現形式,可以簡單以JSON格式表現,也可用複雜的圖表呈現,相同的資訊擁有多種view是可能的。
    隨著Web Service技術普及,view可以依據使用者權限、裝置類型、請求的不同,呈現不一樣的資訊內容或不同的視覺化表示法。
  • Controller:
    接受輸入,並轉換成給model的命令或給view的資料。
    能發出命令,更新model的狀態(如資料庫的CRUD),將model取得的資料傳遞給對應的view去呈現。

以PHP的Codeigniter為例

以PHP的Codeigniter為例,其提供了一個完善的MVC軟體架構,但如果只知MVC所然,而不知MVC所以然的開發人員往往會寫出各種ani-pattern,如以下程式碼:

這個MVC設計有幾個問題:我們沒辦法很直覺的理解model的用意,當我們沒辦法理解how to use this model?what is this function?的時候,model也會很難reuse和維護。

而這個model應該負責處理會員相關資料,但select_join這個function卻沒有將相關的資料表包含在其中,而是利用controller將要查詢的table與columns作為參數傳入select_join()中,這樣又導致controller與model會coupling,使其日後維護變得相當複雜,而我一般會希望能透過controller看出系統的運作流程,所以傾向於controller能簡單的表達抽象且同一層級的邏輯即可。

我會希望controller只需要傳入view取得的會員帳戶與密碼,並將其傳入model對應的function中,即可取得對應的帳戶資料:

其中,明碼加密這件事(原本由encrpt()這個函數處理),應該屬於model層級的規則與邏輯,所以也應該併入model中處理,而不是在controller中處理。接著model->select_join()應該更換為更具有可讀性的名字,如get_member_data(),如此一來我們甚至不需要註解,也能輕鬆的從controller中看出整個controller的處理流程與邏輯。

另外許多工程師也會直接將判斷邏輯寫在view中:

如果能將判斷邏輯放在controller中,更能降低view與controller之間的coupling且命名盡量使用直覺一點的命名,使UI Designer能專注在設計上,而不是留下一堆疑問等著問你:

我是James,一位自由接案工作者
對於軟體開發與接案工作充滿熱忱,截至2018年,不知不覺已經累積11年的時間在這個領域打轉,擁有6年的接案經驗。 寫作是我一個新的嘗試,初衷是希望能讓這個環境變得更好,從三個面向出發:
1.個人:強化團隊成員的生產力與技術力,提供技術觀點與教學、工作方法等硬實力。
2.組織:培養良好的團隊合作態度與企業文化、分享合作與溝通技巧。
3.社會:讓客戶、發包單位知道如何有效處理系統外包,把資源花在刀口上,並透過接案經驗分享促進良好的合作。
FB粉絲頁艾菲肯先生——您最佳的技術夥伴
個人刊物 艾菲肯先生的咖啡時間
工作室網站
Efacani.com