MVC架構的職責劃分原則,對我頗有啓發,分享一下

博主 負責一個項目,用了 Yii Framework 的 MVC 框架,剛開始自覺得結構很穩健。數據庫

可是隨着對業務邏輯理解的深刻,纔開始意識到問題的嚴重。編程

我錯誤地理解了 MVC 中的 Controller,想固然地根據以往的經驗,把全部的業務邏輯都放在 Controlleraction 中去實現。設計模式

因而,每個 Controller代碼都上千行,愈來愈臃腫session

最後,我下定決心重構代碼,起源是一個對外開放 API 接口的需求。架構

按照如今的架構,代碼基本沒法複用,我須要把不少功能再重複寫一遍,這實在是沒法接受。app

面向對象編程不只僅是課本上的名詞啊!框架

真正開始實踐才發現,要有面向對象意識,有全局觀,是多麼可貴的一件事情。yii

1 、到底什麼是 MVC

模型-視圖-控制器(MVC)是一種設計框架(設計模式)jsp

MVC 的目標將業務邏輯從用戶界面的考慮中分離編程語言

這樣,開發者就能夠更容易地改變每一部分而不會影響其餘。

在 MVC 中,

  • Model 表明數據和業務規則
  • View 包含了用戶界面元素,例如文本,表單等;
  • Controller 則管理模型和視圖中的通訊

MVC 在各類編程語言中均有實現,例如 J2EE 應用開發中,

View 可能由 jsp 實現;Controller 是一個 servlet,如今通常用 Struts 實現;Model 則是由一個實體 Bean 來實現。

2 我遇到了什麼問題

Yii Framework 是一個流行的 PHP 框架,它借鑑了 Ruby on Rails 的 ActiveRecord(AR) 概念。

數據庫中的每個 table 均可以用 AR 類來方便地進行增刪改查操做。

它把 AR 當作 Model,並推薦放在一個名爲 models 的目錄下面。

因而,我在自動生成表對應的 AR 以後,便望文生義想固然地認爲已經擁有了 Model 層。

其實,AR只不過是 DAO (數據訪問層),並非 Model 層

咱們的業務幾乎全放在了 Controller 裏:對用戶提交上來的表單進行各類邏輯判斷,進行計算,實例化 AR 對數據進行存儲……

由於一個 Controller 中會有多個 action,每一個 action 都有這樣的業務處理。

最後,我發現個人 Controller 代碼已經超過了 1000 行。

忽然有一天,leader 說,咱們這個系統要開放 API 給現有的舊系統調用,要給第三方接口。

第三方只是要給定一個參數,本系統給出個結果值而已,這其中的業務處理它是不關心的。

壞就壞在這裏,Controller 已經實現了那些業務,但它是接受表單提交的,怎樣可以也接受 SOAP 的 xml 文檔呢?

Controller 和套套同樣,應該越薄越好。

它的職責應該只是接受用戶的輸入,而後馬上轉發給別的類來處理

這樣 Controller 只負責提供不一樣的接口,咱們才能算是將業務邏輯分離出去,而分離出去的業務也很容易進行重用。

分離出來的這部分業務由誰來處理呢?答案應該是 Model

3 View的職責

View部分比較明確,就是負責顯示。

一切與顯示界面無關的東西,都不該該出如今view裏面。

所以,View 中通常不該該出現複雜的判斷語句,以及複雜的運算過程。

能夠有簡單的循環語句、格式化語句。好比,博客首頁的文字列表就是一種循環。

對於PHP的Web應用而言,HTML是View中的主要內容

View應該從不調用Model的寫方法

也就是說,View只從Model中讀取數據,但不改寫Model。

因此咱們說,View和Model是老死不相往來的。

並且,View中不直接訪問$_GET$_POST,應該由Controller傳遞給View。

此外,View通常沒有任何準備數據處理的內容,如查詢數據庫等。

這些通常是放在Controller裏面,並以變量的形式傳給視圖。

也就是說,視圖裏面要用到的數據,就是一個變量

4 Model的職責

對於Model而言,最主要就是保存和輸出信息

好比,Post類必然有一個用於保存博客文章標題的title屬性,必然有一個刪除的操做,這都是Model的內容。

數據、行爲、方法是Model的主要內容

實際工做中,Model是MVC中代碼量最大

Model是邏輯最複雜的地方,由於應用的業務邏輯也要在這裏表示。

注意將Model與Controller區分開。

Model是處理業務方面的邏輯,Controller只是簡單的協調Model和View之間的關係。

只要是與業務有關的,就該放在Model裏面。

數據校驗、public常量和變量,都應該放在model層,

也就是說,有可能被重複使用的屬性或方法,都應該放在model層,一次定義,處處使用。

Model不該該訪問request、session以及其餘環境數據,這些應該由Controller注入。

好的設計,應該是胖Model,瘦Controller

5 Controller的職責

對於Controller,主要是響應用戶請求,決定使用什麼視圖,須要準備什麼數據用來顯示

所以,對於request的訪問代碼,應該放在Controller裏面,好比$_GET$_POST等。

Controller應該僅限於獲取用戶請求數據,不該該對數據有任何操做或預處理,這應該放在 Model 裏面。

對於數據的寫操做,要調用Model類的方法完成。

對於用戶請求的響應,要調用視圖渲染。

此外,通常不要有HTML代碼等其餘表現層的東西,這應該是屬於View的內容。

6 啓示

Yii Framework 的官方文檔中有這麼一段:

In a well-designed MVC application, controllers are often very thin, containing probably only a few dozen lines of code; while models are very fat, containing most of the code responsible for representing and manipulating the data.

在一個設計良好的MVC應用程序中,控制器一般很薄,可能只包含幾十行代碼;而模型很是龐大,包含了大部分負責表示和操做數據的代碼。

相關文章
相關標籤/搜索