日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

.NET平臺上的Model-View-Presenter模式實踐

 zhongzhy 2016-01-08

為什么要寫這篇文章

      筆者當前正在負責研究所中一個項目,這個項目基于.NET平臺,初步擬采用C/S部署體系,所以選擇了Windows Forms作為其UI。經(jīng)過幾此迭代,我們發(fā)現(xiàn)了一個問題:雖然業(yè)務(wù)邏輯已經(jīng)封裝到Services層中,但諸多的UI邏輯仍然彌漫在各個事件Listener中,使得UI顯得臃腫不堪,并且存在諸多重復(fù)性代碼。另外,需求提供方說,根據(jù)實際需要,不排除將部署結(jié)構(gòu)改為B/S的可能性,甚至可能會要求此系統(tǒng)同時支持C/S和B/S兩種部署方式。那么,如果保持目前將UI邏輯編碼到Windows Forms中的方式,到時這些UI邏輯將無法復(fù)用,修改部署方式的代價很大。

      為了解決以上兩個問題,筆者和相關(guān)人員商量后,決定引入既有成熟模式,重新設(shè)計表示層的架構(gòu)方式,并重構(gòu)既有代碼。

      提到表示層(Presentation Layer)的模式,我想大家腦海中第一個閃過的很可能是經(jīng)典的MVC(Model-View-Controller)。我最初也準備使用MVC,但經(jīng)過分析和實驗后,我發(fā)現(xiàn)MVC并不適合目前的情況,因為MVC的結(jié)構(gòu)相對復(fù)雜,Model和View之間要實現(xiàn)一個Observer模式,并實現(xiàn)雙向通信。這樣重構(gòu)起來Services層也必須修改。我并不想修改Services層,而且我想將View和Model徹底隔離,因為我個人并不喜歡View和Model直接通信的架構(gòu)方式。最終,我選擇了MVP(Model-View-Presenter)模式。

      經(jīng)過兩天的重構(gòu)和驗證,目前已經(jīng)將MVP正式引入項目的表示層,并且解決了上文提到的兩個問題。在這期間,積累了少許關(guān)于在.NET平臺上實踐MVP的經(jīng)驗,在這里匯集成此文,和朋友們共享。

UI與P Logic

      首先,我想先明確一下UI和P Logic的概念。

      表示層可以拆分為兩個部分:User Interface(簡稱UI)和Presentation Logic(簡稱P Logic)。

      UI是系統(tǒng)與用戶交互的界面性概念,它的職責有兩個——接受用戶的輸入和向用戶展示輸出。UI應(yīng)該是一個純靜態(tài)的概念,本身不應(yīng)包含任何邏輯,而單純是一個接受輸入和展示輸出的“外殼”。例如,一個不包含邏輯的Windows Form,一張不包含邏輯的頁面,一個不包含邏輯的Flex界面,都屬于UI。

      P Logic是表示層應(yīng)有的邏輯性內(nèi)容。例如,某個文本內(nèi)容不能為空,當某個事件發(fā)生時獲取界面上哪些內(nèi)容,這都屬于P Logic。應(yīng)該指出,P Logic應(yīng)該是抽象于具體UI的,它的本質(zhì)是邏輯,可以復(fù)用到任何與此邏輯相符的UI。

      UI與P Logic之間的聯(lián)系是事件,UI可以根據(jù)用戶的動作觸發(fā)各種事件,P Logic響應(yīng)事件并執(zhí)行相應(yīng)的邏輯。P Logic對UI存在約束作用,P Logic規(guī)定一套UI契約,UI要根據(jù)契約實現(xiàn),才能被相應(yīng)的P Logic調(diào)用。

      下圖展示了UI與P Logic的結(jié)構(gòu)及交互原理。

圖1、UI與P Logic

Model-View-Presenter模式

      MVP模式最早由Taligent的Mike Potel在《MVP: Model-View-Presenter The Taligent Programming Model for C++ and Java》(點擊這里下載)一文中提出。MVP的提出主要是為了解決MVC模式中結(jié)構(gòu)過于復(fù)雜和模型-視圖耦合性過高的問題。MVP的核心思想是將UI分離成View,將P Logic分離成Presenter,而業(yè)務(wù)邏輯和領(lǐng)域相關(guān)邏輯都分離到Model中。View和Model完全解除耦合,不再像MVC中實現(xiàn)一個Observer模式,兩者的通信則依靠Presenter進行。Presenter響應(yīng)View接獲的用戶動作,并調(diào)用Model中的業(yè)務(wù)邏輯,最后將用戶需要的信息返回給View。

      下圖直觀表示了MVP模式:

圖2、MVP模式

      圖2清楚地展示了MVP模式的幾個特點:

      1、View和Model完全解耦,兩者不發(fā)生直接關(guān)聯(lián),通過Presenter進行通信。

      2、Presenter并不是與具體的View耦合,而是和一個抽象的View Interface耦合,View Interface相當于一個契約,抽象出了對應(yīng)View應(yīng)實現(xiàn)的方法。只要實現(xiàn)了這個接口,任何View都可以與指定Presenter兼容,從而實現(xiàn)了P Logic的復(fù)用性和視圖的無縫替換。

      3、View在MVP里應(yīng)該是一個“極瘦”的概念,最多也只能包含維護自身狀態(tài)的邏輯,而其它邏輯都應(yīng)實現(xiàn)在Presenter中。

      總的來說,使用MVP模式可以得到以下兩個收益:

      1、將UI和P Logic兩個關(guān)注點分離,得到更干凈和單一的代碼結(jié)構(gòu)。

      2、實現(xiàn)了P Logic的復(fù)用以及View的無縫替換。

在.NET平臺上實現(xiàn)MVP模式

      這一節(jié)通過一個示例程序展示在.NET平臺上實現(xiàn)MVP的一種實踐方法。本來想通過我目前負責的實際項目中的代碼片段作為Demo,但這樣做存在兩個問題:一是這樣做可能會違反學校的保密守則,二是這個項目應(yīng)用了許多其他框架和模式,如通過Unity實現(xiàn)依賴注入,通過PostSharp實現(xiàn)AOP來負責異常處理和事務(wù)管理等,通過NHibernate實現(xiàn)的ORM等等,這樣如果讀者不了解系統(tǒng)整體架構(gòu)就很難完全讀懂代碼片段,MVP模式不夠突出。因此,我專門為這篇文章實現(xiàn)了一個Demo,其中的MVP實踐方式與實際項目中是一致的,而且Demo規(guī)模小,排除了其他干擾,使得讀者更容易理解其中的MVP實現(xiàn)方式。

      這個簡單的Demo運行效果如下:

圖3、Demo界面

      這個Demo的功能如下:這是一個簡單的點餐軟件。系統(tǒng)中存有餐廳所有菜品的信息,客戶只需在界面右側(cè)輸入菜品名稱和數(shù)量,單擊“添加”按鈕,菜品就會被添加到左側(cè)點餐列表,并顯示此菜品詳細信息。如果所點菜品不存在則軟件會給出提示。另外,在左側(cè)已點餐品列表中右鍵單擊某個條目,在彈出菜單中點擊“刪除”,則可將此菜品從列表刪除。

      下面分步驟介紹應(yīng)用了MVP模式的實現(xiàn)方式。

第一步,解決方法及工程結(jié)構(gòu)

      這個Demo共有三個工程,MVPSimple.Model為Mock方式實現(xiàn)的Services,作為Model;MVPSimple.Presenters為Presenter工程,其中包括Presenter和View Interface;MVPSimple.WinUI為View的Windows Forms實現(xiàn)。

第二步,構(gòu)建Mock方式的Services

      因為重點在于表示層,所以這里的Services使用了Mock方式,并沒有包含真正的業(yè)務(wù)領(lǐng)域邏輯。其中MVPSimple.Model工程里兩個文件的代碼如下:

      FoodDto.cs:

      FoodServices.cs:

第三步,通過View Interface規(guī)定View契約

      如果想實現(xiàn)Presenter和View的交互和無縫替換,必須在它們之間規(guī)定一個契約。一般來說,每一張界面(注意是界面不是視圖)都應(yīng)該對應(yīng)一個View接口,不過由于Demo只有一個頁面,所以也只有一個View接口。

      這里需要特別強調(diào),View接口必須抽象于任何具體視圖而服務(wù)于Presenter,所以,View接口中絕不能出現(xiàn)任何與具體視圖相關(guān)的元素。例如,我們的Demo中是使用Windows Forms作為視圖實現(xiàn),但View接口中絕不可出現(xiàn)與Windows Forms相耦合的元素,如返回一個Winform的TextBox。因為如果這樣做的話,使用其他技術(shù)實現(xiàn)的View就無法實現(xiàn)這個接口了,如使用Web Forms實現(xiàn),而Web Forms是不可能返回一個Winform的TextBox的。

      下面給出視圖接口的代碼。

      IMainView.cs:

      可以看到,IMainView抽象了如圖3所示的界面,但又不包含任何與Windows Forms相耦合的元素,因此如果需要,以后完全可以使用Web Forms、WPF或SL等技術(shù)實現(xiàn)這個接口。

第四步,實現(xiàn)Presenter

      上文說過,一個界面應(yīng)該對應(yīng)一個Presenter,這個Demo里只有一個界面,所以只有一個Presenter。Presenter僅于視圖接口耦合,而并不和具體視圖耦合,最好證據(jù)就是Presenter工程根本沒有引用WinUI工程!代碼如下:

      MainPresenter.cs:

第五步,實現(xiàn)View

      這里我們使用Windows Forms實現(xiàn)View。如果朋友們有興趣,完全可以自己試著用Web或WPF實現(xiàn)以下視圖,同時可以驗證P Logic的可復(fù)用性和視圖無縫替換,親身體驗一下MVP模式的威力。Winform的View代碼如下。

      frmMain.cs:

      可以看到,使用了MVP后,View的代碼變的非常干凈整潔,以前充斥著厚重表示邏輯的事件Listener方法變得“瘦”了許多。

      完成以上幾步后,就可以運行這個Demo看效果了。

總結(jié)

      這篇文章首先討論表示層的組成,說明User Interface和Presentation Logic是表示層的兩個重要組成部分,并分別說明了兩者的作用及交互方式。接著討論了MVP模式。最后,通過一個Demo展示了在.NET平臺上實現(xiàn)MVP的一種實踐方式。應(yīng)該說,MVP很類似簡化了MVC,MVP不但可以分離關(guān)注、使得代碼變得干凈整潔、并實現(xiàn)P Logic的復(fù)用,而且實現(xiàn)起來比MVC在結(jié)構(gòu)上要簡單很多。MVP是一種模式,本身有諸多實現(xiàn)方式,本文只是介紹了筆者使用的一種實踐,朋友們也可以在此基礎(chǔ)上摸索自己的實踐。

Creative Commons License

本文基于署名-非商業(yè)性使用 3.0許可協(xié)議發(fā)布,歡迎轉(zhuǎn)載,演繹,但是必須保留本文的署名張洋(包含鏈接),且不得用于商業(yè)目的。如您有任何疑問或者授權(quán)方面的協(xié)商,請與我聯(lián)系。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多