2011-02-23 20 views
19

我是新來的,請耐心等待。我最近在一些項目中使用了一個MVC框架,過了一段時間後,我對MVC中'Model'的感知功能感到失望。模型在MVC中的用法是什麼?它實際上有用嗎?

我得到了控制器和視圖的用處,我知道表示和邏輯之間的分離對於使代碼在將來更易維護是重要的,儘管不一定更快或更健壯。

如果所有的邏輯都應該放在控制器內部,我沒有看到模型的任何用處,尤其是Active-Record。我們已經有了一種非常強大且易於與數據庫進行通信的語言,對嗎?它被稱爲SQL。對我來說,當模型像活動記錄一樣實現時,它的用處取決於你是否希望你的應用適合多個數據庫。

所以我問的是,如果你只使用一個數據庫,爲什麼要打擾模型和活動記錄?爲什麼不使用SQL?爲什麼會出現額外的複雜性?你們是否有任何案例研究/真實生活中的故事,模型實際上可以做得比使用數據庫類和SQL更好?

同樣,如果我似乎很無知,我很抱歉,但我真的不知道爲什麼模型很重要。謝謝回答。

回答

18

首先,假定模型層必須使用某種ORM,以便將SQL抽象出來。這不是事實:您可以創建一個從Controller層鬆散耦合但與特定DBMS緊密耦合的模型層,因此請避免使用全功能ORM。有一些ORM庫,如Hibernate(Java),NHibernate(。NET),Doctrine(PHP)或ActiveRecord-Rails(Ruby),它們可以爲您生成所有實際的SQL語句;但如果你認爲ORM是不必要的,並且你想手工定義所有的SQL語句,就不要使用它們。

儘管如此,恕我直言,這不是不是意思是你應該把所有你DB相關的邏輯放在控制器層。這被稱爲「胖控制器」方法,並且這是一條多次導致臃腫,不可維護的代碼的道路。您可以將其用於簡單的CRUD項目,但除此之外的任何內容都會要求存在真正的「模型」。

你似乎關心MVC。請閱讀關於TDD的內容。智者曾說過「legacy code is code without tests」。當你知道自動單元測試一樣重要的「真實」代碼時,你會理解爲什麼企業應用程序中有這麼多的層,以及爲什麼你的模型層應該與Controller分開。試圖完成所有事情(演示文稿,業務邏輯,數據持久性)的代碼塊無法輕鬆測試(也無法通過調試)。

編輯

「模型」 是一個有點模糊的術語。根據你看的地方,它可能意味着稍有不同。例如,PHP和Ruby程序員經常使用它作爲Active Record的代名詞,這是不準確的。其他一些開發者似乎認爲「模型」只是某種DTO,這也是不對的。

我寧願用模型的定義爲Wikipedia看到:

MVC,該模型的核心組成部分,捕獲它的問題域,獨立的用戶界面方面的應用程序的行爲。該模型直接管理應用程序的數據,邏輯和規則。

因此,模型是大多數MVC應用程序中最大,最重要的層。這就是爲什麼它通常分爲子層:域,服務,數據訪問等等。該模型通常是通過域暴露,因爲它在那裏你會發現你的控制器將調用的方法。但數據訪問層也屬於「模型」。任何與數據持久性相關的東西業務邏輯屬於它。

+0

感謝您的回答!我想我現在瞭解更多。您提到'需要業務層的存在' - 這個業務層,它是模型嗎? – rickchristie 2011-02-23 17:35:46

+0

感謝您的啓發 - 閱讀TDD - 看起來很棒。將與我的朋友討論。從今天開始,我的編程習慣會改變:) – rickchristie 2011-02-23 18:32:23

1

我始終將模型與數據相關聯,無論數據在何處或如何表示。在MVC V顯示數據和C句柄變化。即使您的控制器中的所有數據都在HashMap中的屏幕上顯示,該HashMap將被稱爲模型。

3

模型應該包含所有的邏輯。控制器只負責與用戶交互相關的邏輯。所有與域相關的功能(稱爲「業務邏輯」)都應放置在模型中並與控制器代碼分離。像這樣,您可以更好地分離問題和代碼可重用性。

例如,假設您正在編寫一個應用程序,以允許用戶輸入有關他們自己的信息並接收飲食重新激活指令。一方面,您可能會將與將用戶提供的數據轉換爲模型部分中的飲食調整列表相關的代碼。這包括數據庫訪問,但也包括與問題(問題域)相關的任何計算,算法和處理。

另一方面,您將代碼記錄在控制器中,顯示錶單,收集表單數據並驗證它們。例如,您可以稍後將api添加到您的應用程序(它使用不同的代碼進行身份驗證,從用戶獲取數據,驗證等)並重新使用代碼生成結果(從模型中)。

這只是該模型適合的一個示例。

6

在大多數現實生活中,來自用戶的數據不會直接進入數據庫。

它必須經常驗證,過濾或轉換。

模型層的作用通常是通過執行這些操作來確保數據正確地到達後端存儲區(通常是數據庫),這些操作不應該是控制器(瘦身控制器,胖模型)的責任,而不是數據庫引擎本身的責任。

換句話說,Model層負責 - 或者「知道」 - 應該如何處理數據。

大多數現代MVC框架提供了指定數據有效性要求(如Rails)的合同的方法。

下面是http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/一個例子:

class Cat 
    validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F' 
    validates_inclusion_of :vaccinated, :in => [true,false] 
    validates_inclusion_of :fiv, :in => [true,false] 
    validates_inclusion_of :age, :within => 1..30 
    validates_each :weight do |record, attr, value| 
     record.errors.add attr, 'should be a minimum of 1 pound' if value and value /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/ 
    validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500 
end 

這裏,有幾個數據有效性的要求不能被數據庫進行處理,而不應在控制器來處理,因爲這些要求的任何修改可能打破代碼在幾個地方。

因此,該模型是確保數據與您的域一致的最佳位置。

還有很多更值得一說這件事,但我覺得解決,似乎對我很重要的一個點,通過實踐經驗:)動機

+0

感謝您的回答!我總是把數據驗證放在我的控制器中,這是一種不好的做法嗎?在我的框架中,驗證器類與模型類是分開的 - 驗證器類本身被編寫爲專門用於控制器內部。那麼,我使用false的框架的模型實現? – rickchristie 2011-02-23 17:20:31

+0

您的意思是驗證/數據要求應該由模型來處理,但事實上,許多應用程序都具有實際基於業務規則的數據要求(例如,不允許此成員每年購買2個以上的iPad) 。如果我正確地理解了你,使用你的例子,這個業務規則將被寫入模型而不是控制器,這是一個很好的MVC練習嗎? – rickchristie 2011-02-23 17:23:34

+1

這是正確的,正如有人在另一個答案中所說的那樣,業務邏輯應該屬於模型層。然後再次,這些圖層之間的邊界非常模糊,並且一些實現將不會遵守瘦身控制器/胖模型範例。 – SirDarius 2011-02-23 17:33:20

7

這不是一個無知的問題了!只是你問這個問題,而不是簡單地忽略整個MVC理論,只要你願意這樣做就很好。 :-)

回答你的問題:概念上,模型只是爲你的數據提供一個很好的抽象。我沒有考慮「如何編寫這個內部連接以獲得所需的所有字段」,而是讓我們根據「我的應用程序的對象如何相互關聯,它們如何相互作用以及如何與之交互從他們那裏獲得我需要的數據「。

以同樣的方式,視圖和控制器幫助您從邏輯中分離顯示,模型可以幫助您將應用程序的邏輯(從用戶的角度來看)從細節層面分離出來,以確定數據實際來自何處以及它是如何表示的內部。

給出一個更具體的例子(如果不是完全現實的話):理論上,你可以用通過SQL查詢獲取所有數據的方式編寫整個應用程序。但後來你意識到你想使用一些noSQL(CouchDB等)引擎,因爲你需要水平縮放。

隨着模型(以及可以同時使用這兩種類型的存儲的框架,當然:-)),您不必擔心細節,因爲所有重要數據都已通過模型以通用方式表示並且視圖和控制器都可以對該表示採取行動。

如果沒有它們,您可能不得不重寫一大段代碼,以便將您的數據提取到新的後端。

這就是無聊的存儲部分。使用純SQL時,定義應用程序對象(即業務邏輯)之間的交互更困難,因爲您不會在SQL中執行此操作(可能無論如何)。

這不是一個完美的解釋(遠離它),但我希望它有幫助。

+0

感謝您的回答!如果我們的應用程序不需要使用另一個數據庫(如果我們不希望更改數據庫或使用多個數據庫)是否可以安全地說 - 模型的用處減少了?如果我正確地理解了你,那麼使用模型將是程序員所採取的風險緩解措施,「以防客戶需要我們更改後端」。 – rickchristie 2011-02-23 17:26:03

+1

在這種情況下,它只是略微減少。模型的好處,特別是能夠抽象出實現細節並專注於實際邏輯的好處通常遠遠超過所有其他模型。如果你只是開始在任何地方傾銷SQL,那麼你最終可能會寫出更多人爲的代碼,因爲你必須將所有數據映射到你的控制器和視圖可以輕鬆使用的地方。根據我的經驗,即使您一開始並未意識到,您最終仍會覺得需要做一些實質上是對象模型的事情。無論如何,你也可以這樣做。 :-) – 2011-02-23 17:34:31

相關問題