嘗試MVP模式

2021-09-09 00:11:52 字數 4474 閱讀 9881

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

public

class

ioccontainer213

}14 }

這裡用到了winforminjectmodule類,它繼承了ninjectmodule,裡面就重寫了load方法實現繫結,由於這裡的繫結時通過配置實現的,所以這裡還涉及到讀取和分析配置資訊

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 }

配置的定義如下

1

<

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

>

bind屬性就是要繫結的類或者介面,to就是繫結到的類,如果只是繫結自己的話就在bind屬性填類名則可,to不用填了。

展示器的基類定義如下

1

public

class presenterbasewhere

t : iview29

10public

t view

1113

set 14}

15 }

以介面的形式對檢視進行訪問的話,就可以避免直接訪問檢視的例項,減少了對檢視的依賴。

考慮到在展示器裡開啟別的展示器管理的檢視時,原本可以構造乙個展示器例項,然後獲取其檢視進行展示,可是在乙個展示器裡構造另乙個展示器,這樣的做法好像不妥,於是定義了乙個類專門用於開啟別的檢視用的。

當要開啟某個檢視(也就是窗體)時,就可以呼叫presentermanager的靜態方法

1

public

class

presentermanager219

}2021public

static

void showview(string

presentername)

2225}26

27public

enum formaction

下面則做乙個簡單的demo,是登入功能的

首先是模型的,先定義了乙個iuser介面,屆時展示器想呼叫模型的方法是就通過這個介面來呼叫,免除了對模型其他成員的訪問

1

public

inte***ce

iuser

2

再由乙個imodeluser實現這個介面

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

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 }

檢視這裡iloginview是繼承了iview介面,裡面宣告了登入檢視應該外放的事件和屬性,那登入介面來說

雖然很明顯看得出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...