深入理解MVC模式

2021-10-01 06:45:23 字數 3729 閱讀 1502

mvc即model,view,controller如上結構圖,分別對應模型,檢視,控制器。就目前而言,我們大多數人更傾向於將軟體的業務邏輯放在controller裡,將資料庫訪問操作的**放入model中,最終軟體的**結構是:view層是介面,controller是業務邏輯,model層神資料庫訪問。

說直白點,大多數人將mvc是當成了三層架構在使用,這樣看起來似乎是沒什麼問題的,畢竟三層架構也是一種和mvc齊名的架構模式。可問題在於用三層架構思路來寫mvc,那麼寫出來的東西既不是三層架構,也不是mvc,成了乙個四不像的東西了。

三層架構的核心思想是面向介面程式設計和各層之間的解耦和可替換性,mvc框架中沒有這種概念,因為mvc要面對的問題本不就是三層架構要面對的問題,所以mvc為基礎寫出來的三層架構是不會舉杯三層架構的核心要義。

下面說說mvc的本質原理和正確使用方式,當然這邊指的神純粹的mvc,適合各類軟體,不僅僅指web框架中的變體mvc,然而萬變不離其宗,文中所述的mvc思想同樣適用於web開發。

mvc要實現的目標神將軟體使用者介面和業務邏輯分離以使**可擴充套件性,可復用性,可維護性,靈活性加強。

view層是介面,model層神業務邏輯,controller層是用來排程view層和model層,將使用者介面和業務邏輯合理的組織在一起,起粘合劑的效果。所以controller中的內容能少則少,這樣才能提供最大的靈活性。

比方說,有乙個view會提交資料給model進行處理實現具體的行為,view通常不會直接提交給model,它會先把資料交給controller,然後controller再將資料**給model。將入此時的程式業務邏輯處理方式有變化,那麼只需要在controller中原來的model換成新實現的model就可以了,控制器的作用就是這麼簡單,用來將不同的view和不同的model組織在一起,順便替雙方傳遞訊息,僅此而已。

合理的使用mvc有很多好處,這不通過乙個反面示例來證明正確的mvc的好處和依據。

如文章開頭所述,很多人偏愛將業務邏輯放在controller中,我是畢竟反對這種做法的,接下來證明這種做法的錯誤。

我們知道在寫程式的時候,業務邏輯的重複使用神經常要面對的場景。如果業務邏輯寫在控制器中,要用他的唯一辦法就是講他提公升到父類中,通過整合來達到**復用的效果。但是這麼做會帶來乙個巨大的***,違背了一項重要的物件導向設計原則:介面隔離。

什麼是介面隔離,這邊簡述一下:介面隔離就是當乙個類需要繼承另外乙個類時,如果被繼承的類中有繼承的類用不到的方法或屬性時,就不要去實現這個繼承。如果真的情非得已的必須要繼承,那麼也需要從被繼承的的類中再提取乙個只包含需要部分功能的新型別,最終去繼承這個新型別才是正確的做法。換句話說,實現繼承的時候,不要去繼承那些用不到的事務。

回到之前的話題,通過繼承父控制器的方式復用業務邏輯,往往會出現為了重用乙個方法而繼承一大堆用不到的方法,表面上看起來沒有什麼問題,但是這會使**變得難以理解,時間久了,**會朝著不健康的方向發展。

要知道,使用繼承的條件是很苛刻的,我們學習物件導向程式設計繼承特性時,第一課就是只有滿足is-a(是乙個)關係時才使用繼承,如果僅僅復用**,並不是我們使用繼承的理由。使用組合是復用**提倡的方式,也就是所謂的has-a(有乙個)的關係,相信每個程式設計師都聽過「少用繼承,多用組合」這句話,這句話是軟體開發行業的先驅們經驗總結出來的,值得我們去遵循。

各model直接神可以相互呼叫的,controller也可以無障礙的呼叫model,因此將業務邏輯放在model中可以靈活的使用組合的方式實現**復用。

而controller之間是不可以相互呼叫的,要復用**只能將**提公升到父類,通過實現繼承,顯然這種做法既不正確也不靈活,因此不提倡。

綜上所述,僅僅神**復用這點,也足以將厚controller,薄model這種不好的mvc思想忘卻。

眾所周知,gof總結過23設計模式,這23種設計模式是某些特地的程式設計問題的特效藥,這是業內公認的。

mvc是一種模式,但卻在gof總結出來這23種設計模式之外,準確的說他不是一種設計模式,他是多種設計模式的組合,並不僅僅神乙個單獨的模式。

組成mvc的三個模式分別是組合模式,策略模式,觀察者模式,mvc在軟體開發中發揮的威力,最終離不開這三個模式的默契配合。

一下內容以這三個設計模式的知識為基礎,如果對著三個設計模式沒概念,或許閱讀困難。

先說組合模式在mvc中扮演的什麼樣的角色,

組合模式只在檢視層活動,檢視層的實現用的就是組合模式,當然這裡指的實現是底層的實現,由程式設計框架廠商做的事情,用不著普通程式設計師做。

組合模式的類層次結構是樹狀的, 而我們做web時檢視層是html頁面,html的結構不正是樹狀的嗎,這其實就是乙個組合模式的應用,只是瀏覽器廠商已經把介面相關的工作幫我們做掉了,但它確確實實是我們應用mvc的其中一部分,只是我們感覺不到罷了,這也是我們覺得view是實現起來最簡單最沒有歧義的一層的原因。

除網頁以外的其他使用者介面程式,如wpf、android、等等都是使用樹狀結構來組織介面控制項物件的,因為組合模式就是從介面設計的通用解決方案總提煉出來的。所以與其說mvc選擇了組合模式,還不如說組合模式是必定會存在mvc中的,因為只要涉及到使用者介面,組合模式就必定存。事實上即使不理解組合模式,也不影響程式設計師正確的使用mvc,組合模式本就存在於程式設計師接觸不到的位置。

然而,觀察者模式和策略模式就顯得比較重要,是實實在在mvc中接觸的到的部分。

觀察者模式有兩部分組成,被觀察的物件和觀察者,觀察者也被稱為監聽者。對應到mvc中,model是被觀察的物件,view是觀察者,model層一旦發生變化,view層即被通知更新。view層和model層互相之間是持有引用的。 我們在開發web mvc程式時,因為檢視層的html和model層的業務邏輯之間隔了乙個http,所以不能顯示的進行關聯,但是他們觀察者和收聽者的關係卻沒有改變。當view通過http提交資料給伺服器,伺服器上的model接受到資料執行某些操作,再通過http響應將結果回送給view,view(瀏覽器)接受到資料更新介面,這不正是乙個接受到通知並執行更新的行為嗎,是觀察者模式的另一種表現形式。

但是,脫離web,當通過**去純粹的表示乙個mvc結構的時候,view和model間無疑是觀察者和被觀察的關係,是以觀察者模式為理論基礎的。即使在web中因為http壁壘的原因導致真正的實現有點走樣,但是原理核心和思路哲學卻是不變的。

最後是策略模式。策略模式是view和controller之間的關係,controller是view的乙個策略,controller對於view是可替換的, view和controller的關係是一對多,在實際的開發場景中,也經常會碰到乙個view被多個controller引用,這即使策咯模式的一種體現,只是不那麼直觀而已。

總結一下,關於mvc各層之間關係所對應的設計模式

view層,單獨實現了組合模式

model層和view層,實現了觀察者模式

view層和controller層,實現了策咯模式

mvc就是將這三個設計模式在一起用了,將這三個設計模式弄明白,mvc將毫無神秘感可言。如果不了解這三個設計模式去學習mvc,那不管怎麼學總歸是一知半解,用的時候也難免不會出想問題。

再次回到最前面討論的業務邏輯應該放在controller還是model的問題上,從設計模式的角度講,策略模式中的策略通常都很小很薄,不會包含太多的內容, controller是乙個策略, 自然不應該在裡面放置過多的內容,否則要替換乙個新的會相當麻煩,與此同時也會破壞view-model的觀察者模式,彷彿view-controller之間即實現了策略模式又實現了觀察者模式,這種混亂是罪惡的根源,是製造焦油坑讓程式設計師陷入其中無法自拔的罪魁禍首。切忌,應當避免。

深入理解MVC

首先我們來看看mvc架構的示意圖 和訪問者互動的是控制層 controller層 控制器 controller 是同類互動的集合,每乙個互動的操作,都對應了乙個動作 action 在thinkphp框架中,全部的控制器類都必須繼承於action。對資料庫進行訪問的是模型層 model層 在think...

深入理解NAT模式

首先說明一下我所遇到的具體情況 本人在主機上安裝的是vmware workstation,在虛擬機器中安裝了ubuntu 8.10。主機上網方式是學校校園網,固定ip,繫結mac,使用的是銳捷客戶端。安裝vm後生成了2個虛擬網絡卡,分別為vmware virtual ethernet adapter...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...