mvp 是從經典的模式mvc演變而來的,難怪看那個結構圖有點相像。
mvc模式的結構圖,m,v,c各代表什麼不說了
mvp模式的結構圖,m和v的含義跟mvc中的結構一樣,區別的就是c(controller)和p(presenter)。感覺這個區別就導致了模式產生性質的變化。至少從幾何角度來看,由乙個穩定的三角型變成一條直線。在mvc中即使在controller對view和model的控制之下,view和model之間仍然有聯絡,至少view上控制項繫結的資料是與model的某個字段有關的。不過在mvp中presenter則把原本mvc中view與model的聯絡砍斷了,view上面那個控制項繫結什麼資料它本身不知道,presenter才知道。這樣view只是負責呈現部分,使得它的職責更單一了。再者presenter不是呼叫view本身,而是呼叫乙個由view實現的介面,這樣使得view與presenter的聯絡更鬆散了。這麼說來,整個mvp模式中的成員一共有四個
瀏覽了一些園友的博文後,我也嘗試實現了乙個mvp模式。專案的結構如下圖。
從上圖可以很明顯的看出mvp的三部分,另外common目錄下存放的主要是mvp模式裡的一些基類,介面等等,本專案還使用了乙個輕量級的ioc框架ninject,為了盡量改動common裡的類,使用ninject時要繫結的介面是實現類以配置的形式來實現,配置的資訊就存放在bindingconfig.xml檔案裡面。
看一下common裡面包含的類
ioccontainer.cs
ioc的容器
iview.cs
檢視介面的基介面
myeventargs.cs
擴充套件了事件和委託的引數
presenterbase.cs
所有展示器的基類
presentermanager.cs
通過展示器展示其檢視
winforminjectmodule .cs
ioc的介面與實現類的繫結
由於對ninject還不是很熟悉,對它的用法解釋不了太多
ioccontainer的定義如下
1這裡用到了winforminjectmodule類,它繼承了ninjectmodule,裡面就重寫了load方法實現繫結,由於這裡的繫結時通過配置實現的,所以這裡還涉及到讀取和分析配置資訊public
class
ioccontainer213
}14 }
1配置的定義如下public
class
winforminjectmodule : ninject.modules.ninjectmodule
216 totype =type.gettype(item.item2);
17bind(bindtype).to(totype);18}
19}2021
private liststring, string>>getbindingconfig()
2237
return
result;38}
39 }
1bind屬性就是要繫結的類或者介面,to就是繫結到的類,如果只是繫結自己的話就在bind屬性填類名則可,to不用填了。<
bindingsetting
>
2<
binding
bind
="testmvp.model.iuser"
to="testmvp.model.usermodel"
/>
3<
binding
bind
="testmvp.view.iloginview"
to="testmvp.view.loginview"
/>
4<
binding
bind
="testmvp.presenter.loginpresenter"
/>
5bindingsetting
>
展示器的基類定義如下
1以介面的形式對檢視進行訪問的話,就可以避免直接訪問檢視的例項,減少了對檢視的依賴。public
class presenterbasewhere
t : iview29
10public
t view
1113
set 14}
15 }
考慮到在展示器裡開啟別的展示器管理的檢視時,原本可以構造乙個展示器例項,然後獲取其檢視進行展示,可是在乙個展示器裡構造另乙個展示器,這樣的做法好像不妥,於是定義了乙個類專門用於開啟別的檢視用的。
當要開啟某個檢視(也就是窗體)時,就可以呼叫presentermanager的靜態方法
1下面則做乙個簡單的demo,是登入功能的public
class
presentermanager219
}2021public
static
void showview(string
presentername)
2225}26
27public
enum formaction
首先是模型的,先定義了乙個iuser介面,屆時展示器想呼叫模型的方法是就通過這個介面來呼叫,免除了對模型其他成員的訪問
1再由乙個imodeluser實現這個介面public
inte***ce
iuser
2
1接著到展示器public
class
usermodel:iuser
29 }
1在構造展示器例項時,給檢視的事件繫結乙個方法,相應登入檢視的登入驗證請求,在改方法內呼叫模型的方法驗證使用者名稱密碼,把結果通過委託的引數傳遞給檢視。如果驗證通過了就隱藏登入檢視,顯示主介面。public
class loginpresenter:presenterbase256
public loginpresenter(iloginview view):base
(view)711
12void view_onlogin(object
sender, myeventargs e)
1321
}22 }
最後到檢視
1檢視這裡iloginview是繼承了iview介面,裡面宣告了登入檢視應該外放的事件和屬性,那登入介面來說public
inte***ce
iloginview:iview25
6string passwordboxtext 7}
89public
partial
class
loginview : form,iloginview
1015
16private
void button1_click(object
sender, eventargs e)
1723
24public
event
myeventhandler onlogin;
2526
public
string
passwordboxtext
2729
set 30}
3132
public
string
idboxtext
3335
set 36}
37 }
雖然很明顯看得出id後的輸入框的值是使用者id,password後面的輸入框的值是使用者密碼,但是這些對於乙個檢視來說都是不知其含義的,知道含義的是展示器,檢視只是把值外放出去給展示器獲取。正如一位園友說的,檢視就該盡量吧控制項多外放出去。不過我覺得某些簡單的介面邏輯還是放在檢視上比較好,例如單擊了某個按鈕使得另乙個輸入框變灰之類的。
這樣就牽強地使用了一下mvp模式,有位園友在討論mvc時說過,沒發揮到mvc的優勢時乾脆用回以前的webform,mvp也一樣吧,期待能真正用上它的時候。由於最近都是從事c/s的開發,對c/s比較熟悉,做的這個小嘗試也是用winform的,但轉到webform上估計也不難,展示器管理那裡要更改一下。
何謂MVP模式?
mvp 是從經典的模式mvc演變而來,它們的基本思想有相通的地方 controller presenter負責邏輯的處理,model提供資料,view負責顯示。作為一種新的模式,mvp與mvc有著乙個重大的區別 在mvp中view並不直接使用model,它們之間的通訊是通過presenter mvc...
MVP模式入門
一 什麼是mvp?mvp 全稱 model view presenter mvp 是從經典的模式mvc演變而來,它們的基本思想有相通的 地方 controller presenter負責邏輯的處理,model提供資料,view負責顯示。model 資料層,和mvc中的m一樣,用來放資料的處理 比如網...
MVP設計模式
建立ipresenter介面,把所有業務邏輯的介面都放在這裡,並建立它的實現presentercompl 在這裡可以方便地檢視業務功能,由於介面可以有多種實現所以也方便寫單元測試 建立iview介面,把所有檢視邏輯的介面都放在這裡,其實現類是當前的activity fragment activity...