




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
38/41.NET平臺的分層架構與設計模式應用研究一、緒論71.1B/S系統概述71.2分層架構概述81.3設計模式概述91.4研究背景101.4.1.NET平臺分層架構的現狀與可研究性101.4.2研究目的111.4.3研究方法11二、關鍵性原則與總體架構122.1關鍵性原則122.1.1分層架構逐漸調用原則與單向調用原則122.1.2單一職責原則122.1.3開放-封閉原則122.1.4依賴倒轉原則132.1.5迪米特原則132.2總體架構132.2.1層次劃分132.2.2職責劃分132.2.3模塊劃分與交互設計14三、關鍵性構件與各層次實現153.1實體的識別與數據庫設計153.1.1識別實體153.1.2數據庫設計153.2實體類設計183.2.1實體類概述、作用與設計目標183.2.2實體類的設計方案與其比較193.2.3實體類的實現193.3接口設計193.3.1接口概述與其作用193.3.2數據訪問層接口的設計203.3.3業務邏輯層接口的設計21四、三層架構中常用的設計模式224.1依賴注入與控制反轉224.2AbstractFactory模式在三層架構的應用244.3三層架構中的外觀模式(Facade)25[參考文獻]26附錄一:代碼摘要27用戶實體類:BookStoreModels.Users.cs27用戶數據訪問層接口:BookStoreIDAL.IUsers.cs29用戶業務邏輯層接口:BookStoreBLL.Users.cs31抽象工廠類:BookSoreDALFactory.AbstractDALFactory.cs34[摘要]“編程是一門技術,更加是一門藝術[6]”。在傳統的系統設計中,將對數據庫的訪問、業務邏輯與可視元素等代碼混編。這樣的不但代碼風格不美觀,所寫的程序更是可讀性差,耦合度高,不容易維護,靈活性差,不容易擴展,更談不上復用。為了解決這個問題,有人提出了N層架構思想,即將各個功能塊明確分開,放置在獨立的層中,各層之間通過協作來完成整體功能。本文只是以網上購物為例,結合分層架構中常用的設計模式對.NET平臺上的分層架構進行深入的研究和探討,以期其總結出的理論能給.NET平臺的開發人員一個指導性作用。[關鍵詞].NET,分層架構,設計模式一、緒論1.1B/S系統概述B/S結構(Browser/Server,瀏覽器/服務器模式),是WEB興起后的一種網絡結構模式,WEB瀏覽器是客戶端最主要的應用軟件。這種模式統一了客戶端,將系統功能實現的核心部分集中到服務器上,簡化了系統的開發、維護和使用。客戶機上只要安裝一個瀏覽器(Browser),如NetscapeNavigator或InternetExplorer,服務器安裝Oracle、Sybase、Informix或SQLServer等數據庫。瀏覽器通過WebServer同數據庫進行數據交互。B/S結構圖在這種結構下,用戶工作界面是通過WWW瀏覽器來實現,極少部分事務邏輯在前端(Browser)實現,但是主要事務邏輯在服務器端(Server)實現,形成所謂三層3-tier結構。相對于C/S結構屬于“胖”客戶端,需要在使用者電腦上安裝相應的操作軟件來說,B/S結構是屬于一種“瘦”客戶端,大多數或主要的業務邏輯都存在在服務器端,因此,B/S結構的系統可以在任何地方進行操作而不用安裝任何專門的軟件,只要有一臺能上網的電腦就能使用,客戶端零維護。系統的擴展非常容易。B/S結構系統的產生為系統面對無限未知用戶提供了可能。當然,與C/S結構相比,B/S結構也存在著系統運行速度較慢,訪問系統的用戶不可控的弱點。以目前的技術看,局域網建立B/S結構的網絡應用,并通過Internet/Intranet模式下數據庫應用,相對易于把握、成本也是較低的。它是一次性到位的開發,能實現不同的人員,從不同的地點,以不同的接入方式(比如LAN,WAN,Internet/Intranet等)訪問和操作共同的數據庫;它能有效地保護數據平臺和管理訪問權限,服務器數據庫也很安全。特別是在JAVA這樣的跨平臺語言出現之后,B/S架構管理軟件更是方便、快捷、高效。1.2分層架構概述在分解復雜的軟件系統時,軟件設計者用得最多的技術之一就是分層。在計算機本身的架構中,可以看到:到處都有分層的例子:不同的層從包含了操作系統調用的程序設計語言,到設備驅動程序和CPU指令集,再到芯片部的各種邏輯門。網絡互聯中,FTP層架構在TCP之上,TCP架構在IP之上,IP又架構在以太網之上。當用分層的觀點來考慮系統時,可以將各個子系統想像成按照“多層蛋糕”的形式來組織,每一層都依托在其下層之上。在這種組織方式下,上層使用了下層定義的各種服務,而下層對上層一無所知。另外,每一層對自己的上層隱藏其下層的細節。多層架構的提出,是軟件開發思想的一個重大進步。它的出現,在很大程度上解決了軟件開發中的強耦合問題,也為編寫代碼清晰、可維護性良好的系統提供了思想基礎。MartinFowler在《企業應用架構模式》一書中對分層架構的優勢描述如下:開發人員可以只關注整個架構中的其中一層可以很容易地用新的實現替代原有層次的實現可以降低層與層之間的依賴有利于標準化有利于各層邏輯的復用概括來說,分層架構設計可以達到如下目的:分散關注,松散耦合,邏輯復用,標準定義。當然,任何事物有利也有弊。分層架構的一大缺點就是降低了系統的性能,因為本來直接完成的功能現在需要多次調用才能完成,自然使得性能下降。所以,分層架構可以說是以犧牲系統性能換取可維護性的手段。可以看出,系統的性能和可維護性是一對矛盾,魚和熊掌和難兼得,所以在使用分層架構設計系統時,要把握一個度,不能過于極端的強調性能或可維護性,而是應該根據系統的具體情況,取兩者的折中。1.3設計模式概述目前,軟件設計模式尚處在迅速發展之中,越來越多的研究人員正在把注意力投向軟件設計模式的研究。關于軟件設計模式的研究工作主要在國外展開的,國到目前為止對于軟件設計模式的研究尚處在起步階段。設計模式這個概念最初產生于建筑行業。設計師(設計建筑物而不是計算機系統)意識到他們需要共享有關正確設計技術的想法。這些想法是在可以使設計師團體從分享經驗和教訓中獲益的設計模式中形成的。設計模式在80年代后期從建筑業進入計算機系統領域。面向對象(Object-oriented,OO)原則逐漸得到普與,而設計模式成為培育新的OO追隨者的最佳實踐。RichardGamma等(人們通常把他們稱作GangofFour[GoF])編著的《DesignPatterns:ElementsofReusableObject-OrientedSoftware》一書使設計模式成為萬眾矚目的焦點。隨著設計模式逐漸普與,他們所涉與的領域就像“BenandJerry”效應那樣也逐漸廣泛起來。因此,它就是設計模式,和普通的OO設計模式一樣來源于GoF的著作,但是現在包括了專為開發語言、應用服務器、行業合成等提供的設計模式。設計模式通常根據一些公共特性而組合在一起。GoF的著作把設計模式劃分為三類:Creational、Behavioral和Structural。用于J2EE的設計模式通常劃分為表現層(PresentationTier)、業務邏輯層(BusinessLogicTier)和集成層(IntegrationTier)。這種分組方式可以使描述所有設計模式共享的公共細節更加輕松,或者使設計模式的分類和發現更加輕松。[4]盡管設計模式本身并不要求一定用某種語言來實現,但脫離了具體的實現,就無法真正理解設計模式。GOF的《設計模式》是經典之作,但畢竟距現在已經十幾年了。這個期間開發平臺已經進化了多代,很多新技術已經應用到編程中。有些技術可以簡化設計模式的實現,有些技術已經采用了設計模式。因此,設計模式必須針對所使用的編程語言和開發平臺,一定要注意,不是將《設計模式》中的例子轉換為C#或者其他語言就等于知道如何實現設計模式了,而是要關注設計模式的精髓,并結合具體的語言特點完成其實現。就.NET而言,很多技術可以簡化設計模式的實現,例如,采用反射技術實現工廠和采用委托技術實現模板方法等。另外,由于國情不同和業務的發展,使得設計模式的選擇和運用更具有特殊性,特別是在業務變化頻繁項目中的選擇和運用。1.4研究背景1.4.1.NET平臺分層架構的現狀與可研究性 微軟(Microsoft)公司的.NET平臺憑借其先進的設計思想、豐富的類庫、強大的能力和完善的IDE與開發幫助文檔獲得了眾多開發者的青睞。尤其在Web開發平臺方面,ASP.NET憑借其完善的面向對象模型和獨樹一幟的控件式開發方式將Web開發這一技術領域提高到一個前所未有的新境界。 然而,令人遺憾的是,到目前為止,仍缺少一個成熟的基于.NET平臺的經典分層架構體系。反觀其競爭對手Java平臺,從E到輕量級框架,基于J2EE平臺的分層架構已相當成熟和完善。目前,基于.NET平臺的分層架構一般都是模仿微軟官方給出的分層例——“.NETPetShop”。雖然“.NETPetShop”是一個經典的基于.NET平臺的B/S系統分層架構示例,然而也有許多不足,如: 1.結構過于復雜,有點為分層而分層的感覺,對實際項目指導力不足。 2.實現方法單一。如數據訪問層是使用的樸素實現,即手工組合參數,然后動態生成SQL語句和調用存儲過程。然而在實際中,可能有更多的實現方式,例如通過ORM實現,這就需要進一步討論數據訪問層的共性,從更高的抽象層次上對其進行理解和掌握,而不是僅僅把數據訪問層看成一種具體的實現。 基于以上幾點,可以看出,現在迫切需要形成一套理論,來指導.NET平臺上的分層架構開發,而不是讓其僅僅停留在模仿階段。1.4.2研究目的 本論文的研究目的,是力圖通過對分層架構思想、設計模式、軟件工程、.NET平臺以與Web2.0思想等論題的研究,尋找一種合理、簡練、通用、易用、安全、具有良好的可維護性和可擴展性并且融入最新技術元素的基于.NET平臺的分層架構模式。而且要通過一個完整的系統實例展現出來。 另外,設計模式也是本課題要討論的話題之一。因為,做架構設計離不開設計模式。文章中在用到設計模式的地方,進行與分層架構模型有關的討論,并研究其在與.NET平臺的結合中的特殊問題。1.4.3研究方法 本文是一個兼具理論與應用的課題,所以,在研究過程中,兩方面都要涉與到。基于此,我們對此課題采取的研究方法是:收集需求、提出方案、設計實現、驗證效果。 首先,應該從整體到部分,對整個分層架構體系各個需求進行收集,明確各部件的職責;然后,針對其職責,提出幾種設計方案,并進行設計實現;最后,從耦合度、可擴展性、可維護性和性能等多方面對方案進行驗證,提出對解決方案的評價。 為了避免脫離實際,在研究本課題的過程中,將逐步完成一個實際的系統,而所有的理論,都將直接作用在此系統上,貫穿于一個完整的系統開發過程中,從而讓理論在實踐中得到檢驗。 本文研究的Demo將是一個網上購物系統,之所以選擇網上購物系統,有以下幾點原因: 1.規模適中。網上購物系統的規模適中,既能起到示例的作用,又不會因為太過復雜而影響進度。 2.業務邏輯熟悉。一般來講,在做某個系統時,業務邏輯的設計要和領域專家合作,因為一般情況下軟件開發人員對其他領域的業務流程并不熟悉。而網上購物系統是我們常用的一種系統,大多數人對其業務邏輯非常熟悉。這樣就可以免去在研究業務上耗費精力,而將主要經歷放在架構的研究上。二、關鍵性原則與總體架構2.1關鍵性原則 在軟件開發技術的發展過程中,出現了很多優秀的思想與模式。這些思想和模式凝結了無數程序設計人員的實踐經驗,是軟件開發領域的精華。其中的很多思想,對分層架構設計也有著重要的指導作用,下面將列出一些在本課題研究中起著重要作用的指導思想和所設計的架構應遵循的原則。2.1.1分層架構逐漸調用原則與單向調用原則 現在約定將N層架構的各層依次編號為1、2、…、K、…、N-1、N,其中層的編號越大,則越處在上層。那么,我們設計的架構應該滿足以下兩個原則:1.第K(1<K<=N)層只準依賴第K-1層,而不可依賴其他底層。2.如果P層依賴Q層,則P的編號一定大于Q。其中第一個原則,保證了依賴的逐層性,與整個架構的依賴是逐層向下的,而不能跨層依賴。第一個原則,則保證了依賴的單向性,與只能上層依賴底層,而不能底層反過來依賴上層。2.1.2單一職責原則就一個類而言,應該僅有一個引起它變化的原因。軟件設計真正要做的許多容,就是發現職責并把那些職責相互分離。如果你能夠想到多于一個的動機去改變一個類,那么這個類就具有多于一個的職責,一個類承擔的職責過多,就等于把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生是,設計會遭受到意想不到的破壞[2]。2.1.3開放-封閉原則開放-封閉原則,是說軟件實體(類、模塊、函數等等)應該可以擴展(Openforextension),但是不可修改(Closedformodification)。開放-封閉原則是面向對象設計的核心所在。遵循這個原則可以帶來面向對象技術所聲稱的巨大好處,也就是可維護、可擴展、可復用、靈活性好。開發人員應該僅對程序中呈現出頻繁變化的那些部分做出抽象,然而。對于應用程序中的每個部分都刻意地進行抽象和抽象本身一樣重要[2]。 具體到N層架構中,可以描述為:當K-1層有了一個新的具體實現時,它應該可以在不修改K層的情況下,與K層無縫連接,順利交互。2.1.4依賴倒轉原則依賴到轉原則,A.高層模塊不應該依賴底層模塊。兩個都應該依賴抽象;B.抽象不應該依賴細節,細節應該依賴抽象[2]。如果不管高層模塊還是底層模塊都依賴于抽象,具體一點就是借口或抽象類,只要接口是穩定的,那么任何一個的更改都不用擔心其他收到影響,這就使得無論高層模塊還是底層模塊都可以很容易地被復用[6]。2.1.5迪米特原則迪米特法則(LoD)也叫最少知識原則,如果兩個類不必彼此直接通信,呢么這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用[3]。迪米特法則其根本思想是強調了類之間的松耦合。類之間的耦合越弱,越有利于復用,一個處在弱耦合的類被修改,不會對有關系的類造成波與。也就是說,信息的隱藏促進了軟件的復用。[6] 例如,在外觀模式中,為子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用[1]。外觀模式完美地體現了迪米特法則的思想。而企業軟件中的三層或N層架構,層與層之間地分離其實就是外觀模式的體現。2.2總體架構2.2.1層次劃分 目前,典型的分層架構是三層架構,即自底向上依次是數據訪問層、業務邏輯層和表示層。這種經典架構經歷了時間的考驗和實踐的多次檢驗,被認為是合理、有效的分層設計,所以,在本課題中,將沿襲這種經典架構,使用數據訪問層、業務邏輯層和表示層的三層架構體系。2.2.2職責劃分 在典型的三層架構中,對層次各自的職責劃分并沒有一個統一的規,綜合現有的成功實踐和.NET平臺的特殊性,在本課題中將三層架構的職責劃分如下: 數據訪問層——負責與數據源的交互,即數據的插入、刪除、修改以與從數據庫中讀出數據等操作。對數據的正確性和可用性不負責,對數據的用途不了解,不負擔任何業務邏輯。 業務邏輯層——負責系統領域業務的處理,負責邏輯性數據的生成、處理與轉換。對流入的邏輯性數據的正確性與有效性負責,對流出的邏輯性數據與用戶性數據不負責,對數據的呈現樣式不負責。 表示層——負責接收用戶的輸入、將輸出呈現給用戶以與訪問安全性驗證。對流入的數據的正確性和有效性負責,對呈現樣式負責,對呈現友好的錯誤信息負責。2.2.3模塊劃分與交互設計 綜合以上分析,可在宏觀上將整個系統分為一下幾個模塊: 實體類模塊——一組實體類的集合,負責整個系統中數據的封裝與傳遞。 數據訪問層接口族——一組接口的集合,表示數據訪問層的接口。 數據訪問層模塊——一組類的集合,完成數據訪問層的具體功能,實現數據訪問層接口族。 業務邏輯層模塊——一組類的集合,完成業務邏輯層的具體功能,實現業務邏輯層接口族。 表示層模塊——程序與可視元素的集合,負責完成表示層的具體功能。 輔助類模塊——完成輔助性功能。 各個模塊的劃分與交互性如圖2.1所示:(其中單向箭頭表示實泛化,雙向箭頭表示依賴與調用)表示層表示層業務邏輯層數據訪問層數據源實體類輔助類IDAL三、關鍵性構件與各層次實現3.1實體的識別與數據庫設計3.1.1識別實體 根據對網上購物系統的需求分析,可以識別出一下幾個實體:用戶(Users):代表使用網上購物系統的用戶,包括注冊會員、管理員。圖書(Books):代表庫存的圖書。圖書分類(Categories):代表庫存圖書的種類。圖書(Publishers):代表圖書。訂單(Orders):代表使用網上購物系統的用戶的訂單。圖書訂單(OrderBook):代表使用網上購物系統的用戶的訂單的詳細信息。關鍵字搜索(SearchKeyword)3.1.2數據庫設計邏輯結構設計附件表(Attachment)(可存入非主要字段)字段名字段類型長度允許空說明附件IDIdint否主鍵圖書IDBookIdint否所在的圖書ID附件或附加信息類型AttaTypeint否如0(默認)表示圖片,1表示編輯推薦容附件或附加信息AttaValueNvarchar(MAX)否附件或附加信息信息圖書表(Books)字段名字段類型長度允許空說明圖書IDIdint否主鍵,與Attachment表的BookId構成主外鍵圖書標題Titlenvarchar(200)否作者Authornvarchar(200)否IDPublisherIdint否Publishers表的外鍵出版日期PublishDatedatetime否標準書號ISBNnvarchar(50)否字數WordsCountint否圖書字數單價UnitPricemoney否折扣Discountfloat是容簡介ContentDescriptionnvarchar(MAX)是作者簡介AuthorDescriptionnvarchar(MAX)是是否存在編輯推薦EditorCommentnvarchar(MAX)是是否存在圖片Imagesnvarchar(50)是Image的URL圖書目錄TOCnvarchar(MAX)是圖書分類IDCategoryIdint否Categories表的外鍵點擊數Clicksint是是否推薦IsEditorCommentint是0代表否,1代表是圖書分類表Categoriges字段名字段類型長度允許空說明分類IDIdint否主鍵與Users表的CategoryId構成主外鍵分類名Namenvarchar(200)否圖書表Publishers字段名字段類型長度允許空說明名IDIdint否主鍵與Users表的PublisherId構成主外鍵名稱Namenvarchar(200)否用戶表Users字段名字段類型長度允許空說明用戶IDIdint否主鍵與Orders表的UserId構成主外鍵登陸賬號LoginIdnvarchar(50)否登錄密碼LoginPwdnvarchar(50)否用戶真實Namenvarchar(50)否Addressnvarchar(200)否聯系Phonenvarchar(100)否Mailnvarchar(100)否用戶角色UserRoleIdint否0表示普通會員1表示管理員用戶狀態UserStateIdint否1表示未審批0表示正常2表示凍結訂單表(Orders)字段名字段類型長度允許空說明訂單IDIdint否主鍵與OrderBook表的OerderId構成主外鍵訂購日期OrderDatedatetime否用戶IDUserIdint否Users表的外鍵總額TotalPricedecimal(10,2)否訂單狀態OrderStatenvarchar(10)否已發貨已收貨已收款圖書訂單表(OrderBook)字段名字段類型長度允許空說明圖書訂單IDIdint否主鍵訂單IDOrderIdint否Orders表的外鍵圖書IDBookIdint否Books表的外鍵訂購數量Quantityint否單價UnitPriceDecimal(18,0)否3.2實體類設計3.2.1實體類概述、作用與設計目標 實體類是對實體的封裝,是現實世界中實體的計算機表示。它通常包括私有變量與對應的get、set方法,而在C#語言中,將get、set方法又組合成屬性。這些私有變量或者屬性,則對應現實實體相應的屬性。 實體類的作用主要有兩個,一是作為現實實體的計算機代表,二是數據的傳遞。在分層架構的應用中,數據正是封裝在實體類中,然后以實體類為載體在各個層次間傳遞。這樣不但符合面向對象設計的原則,也便于對數據存取進行控制。 理想情況下,實體類中不能含有任何邏輯,它應該單純是數據的封裝。所以,它不應該有方法,當然構造函數除外。 基于以上分析,我們設計的實體類,應該是準確、干凈、易用。準確表明實體類應該準確無誤地表示現實中的實體,干凈表示實體類應該僅包含數據的封裝而不摻雜任何邏輯或者與數據封裝無關的東西,易用表示實體類應該很容易地用來在各層之間傳遞數據。3.2.2實體類的設計方案與其比較 一般認為,實體類的設計非常簡單,而且系統中僅需要一種實體類即可。但是,在分層架構中出現了一些新情況,導致了一些變化。我們知道,實體類負責整個系統數據的傳輸,從表示層到數據訪問層,甚至在JavaScript中,都能看到它的身影,因此可以說,它與各層的耦合度是相當高的,由于實體類的存在,系統各層之間多了一個間接的耦合,我把它叫做實體類耦合。實體類耦合有時是非常危險的。 理想的分層架構,應該是各層可獨立替換的。例如,將數據訪問層替換掉,并不應該導致業務邏輯層和表示層的絲毫改動,只要實現了約定接口的數據訪問層,都應該可以替換進來。但是,如果某一個新的數據訪問層使用的實體類和原實體類不一致,那么當這個數據訪問層替換進來后,就需要修改其它所有層次,將其中的實體類進行替換。這嚴重破壞了開放-關閉原則,也嚴重影響了分層架構的質量。 這種情況,在現實中是完全可能發生的。例如,我們之前是用的樸素數據訪問層設計,即動態生成SQL語言或調用存儲過程的方法,那么,我們的實體類應該是已經設計好的“干凈”實體類。而某一天,我們需要改用原有框架設計數據訪問層,而假設原有機制用到的實體類是自動生成的,它是不“干凈”的,其中添加了很多專為原有機制而設計的代碼。這些實體類,與原實體類完全不兼容。 為避免這種情況,就需要對實體類耦合解耦。解耦的方法有兩種:一是使用Adapter模式,二是使用轉換器。不過,本文并不會對這兩種方法做詳細的介紹。3.2.3實體類的實現 本課題約定,實體類命名規則為“表名”。 以用戶實體為例,Users的完整代碼見附錄一。3.3接口設計3.3.1接口概述與其作用 這里的“接口”一詞,特指在分層架構中底層向頂層開放的可調用方法,具體到本課題的Demo中,特指數據訪問層接口和業務邏輯層接口。 接口在技術上編寫難度不大,但是其意義十分重大。總體來說,接口有著一下幾個作用:接口明確了各層次的職責。接口決定了各個層次具體需要實現的功能。接口形成了整個分層架構的骨架接口暴露了層次的API,為上層提供了依賴點。 因此,接口的設計實際上處在現實需求和程序實現之間,起到承上啟下的用。它決定了需求分析中的各個需求如何合理地映射成各個層次的不同方法。所以接口的設計應該在需求分析的基礎上進行。3.3.2數據訪問層接口的設計 因為接口直接關系到層次的職責,所以,在設計數據訪問層接口之前,需要對數據訪問層的職責進行明確。 在本課題中,將數據訪問層職責敘述如下:數據訪問層負責與數據源的交互,負責數據的創建、刪除、更新與查詢工作。它不應該包含任何業務邏輯或可視性元素,對它所處理數據的業務意義是“無知”的。它與數據庫系統一起負責數據完整性。 具體來說,數據訪問層的接口一般包含以下幾種類型的操作: 創建:在數據庫中插入新記錄,無返回值或返回表示操作狀態的標志值。 刪除:在數據庫中刪除符合條件的記錄,一般無返回值或返回表示操作狀態的標志值。 更新:將數據庫中符合條件的記錄更新,一般無返回值或返回表示操作狀態的標志值。 單實體查詢:從數據庫中讀出符合條件單條記錄的信息,一般返回單個實體類。 集合實體查詢:從數據庫中讀出符合條件的多條記錄的信息,一般返回實體類集合。 函數查詢:根據一定的函數規則,根據數據記錄查詢相應的函數值,如查詢某個表的記錄數目,返回指定函數值。 以實體用戶為例,根據需求分析,數據訪問層接口設計如表所示。需求接口參數返回值操作類型獲取用戶信息GetModel用戶名用戶實體類單實體查詢獲取全部用戶GetModelList無用戶實體類集合實體查詢獲取特定狀態用戶GetModelList用戶狀態用戶實體類集合實體查詢添加新用戶AddUser用戶實體類表示是否成功的布爾值創建刪除用戶DeleteUser用戶ID表示是否成功的布爾值刪除更新用戶信息UpdateUser用戶實體類表示是否成功的布爾值更新修改用戶密碼UpdatePwd用戶實體類表示是否成功的布爾值更新修改用戶狀態UpdateUserState用戶狀態ID、用戶ID表示是否成功的布爾值更新判斷是否存在此用戶IsExist用戶名表示是否成功的布爾值函數查詢 具體IUsersDAL的實現代碼請參考附錄一3.3.3業務邏輯層接口的設計 與數據訪問層接口的設計一樣,在設計業務邏輯層的接口前,首先應明確其職責。 本課題將業務邏輯層的職責敘述如下:業務邏輯層負責完成與系統領域相關的業務邏輯操作,實現過程中的數據訪問操作通過調用數據訪問層實現。它對業務相關的數據有效性負責,但是不負責UI輸入數據的有效性。業務邏輯層中不能含有與顯示相關的邏輯,不能決定或影響數據最終的呈現樣式。 由于不同領域的業務邏輯差別很大,所以無法像數據訪問層那樣對接口操作做出明確的分類。 在實際項目開發中,業務邏輯層接口的設計往往要和領域專家合作。而在本課題的Demo中,由于網上購物系統的領域業務大家都很熟悉,所以不用進行專門的領域邏輯調研。 下面以用戶實體為例,業務邏輯層接口設計如表所示。需求接口參數返回值操作類型獲取用戶信息GetModel用戶名用戶實體類單實體查詢獲取全部用戶GetModelList無用戶實體類集合實體查詢獲取特定狀態用戶GetModelList用戶狀態用戶實體類集合實體查詢添加新用戶AddUser用戶實體類表示是否成功的布爾值創建刪除用戶DeleteUser用戶ID表示是否成功的布爾值刪除更新用戶信息UpdateUser用戶實體類表示是否成功的布爾值更新修改用戶密碼UpdatePwd用戶實體類表示是否成功的布爾值更新修改用戶狀態UpdateUserState用戶狀態ID、用戶ID表示是否成功的布爾值更新判斷是否存在此用戶IsExist用戶名表示是否成功的布爾值函數查詢具體UsersBLL的實現代碼請參考附錄一。四、三層架構中常用的設計模式4.1依賴注入與控制反轉 依賴注入(DependencyInjection)和控制反轉(InversionofControl)是同一個概念。具體含義是:當某個角色(調用者)需要另一個角色(被調用者)的協助時,在傳統的程序設計過程中,通常由調用者來創建被調用者的實例。但在具有依賴注入的系統里,創建被調用者的工作不再由調用者來完成,因此稱為控制反轉。創建被調用者實例的工作通常由Ioc容器來完成,然后注入調用者,因此也稱為依賴注入。 具體到分層架構中,依賴注入可以這樣理解:當上層類的需要調用下層類功能時,不再是由上層類直接實例化下層類,而是通過IoC容器獲取一個下層類的實例,然后注入到上層類中。 以用戶實體的業務邏輯層調用數據訪問層為例,在沒有依賴注入機制的系統中,用戶的業務邏輯層類直接實例化數據訪問層類,如圖4.1(a)所示。在加入依賴注入機制后,實例化數據訪問層的任務就交給了IoC容器,如圖4.5(b)所示圖4.1(a)非IoC耦合示意圖4.1(b)IoC耦合示意 這樣做的好處是什么呢?前面已經提到過,在我們設計的分層架構中層次之間一定不能出現具體耦合。如果按照圖4.1(a)的模式,業務邏輯層勢必要實例化具體的數據訪問層類,這就造成了緊耦合。而在依賴注入機制下,業務邏輯層可以只依賴數據訪問層的接口,至于在運行時得到的是哪種數據訪問層類,它并不需要知道,他只需從IoC中獲得相應的類,然后調用它的方法完成任務就行了。而IoC部可以有一套配置機制,這樣就可以根據不同的配置信息,動態決定實例化那一種數據訪問層類,從而實現了兩個層次間的解耦。由于團隊的各方面的因素,本文的在線購物實例采用了圖4.1(a)的模式。圖4.1(b)的模式并不展開討論,想了解這方面知識的讀者請查閱相關的資料。4.2AbstractFactory模式在三層架構的應用 AbstractFactory模式是在依賴注入機制中廣泛采用的設計模式,Spring的IoC容器就采用了這個經典模式。它的中文譯名叫做“抽象工廠”,其定義是這樣的:提供一個接口,用于創建相關或依賴對象的家族,而不需要指定具體類。圖4.2抽象工廠模式圖4.2是AbstractFactory模式的示意圖。IFactory為工廠接口,它部定義了生產一系列產品的方法。其它所有工廠都必須實現這個接口,但它們生產的產品系列是不一樣的,而一系列產品的每一種產品都實現自同一個產品接口。這樣,客戶(Client)僅需要依賴工廠接口和產品接口。如果配置文件決定實例化哪一個工廠,則客戶就能在運行時動態獲得不同的產品系列,從而系統獲得了依賴注入的功能。 下面具體到本課題中,討論抽象工廠在依賴注入機制中的應用。以數據訪問層注入到業務邏輯層為例(業務邏輯層注入到表示層的原理類似),先假設系統僅有用戶一個實體,并且我們的系統需要能訪問SQLServer和Access兩個數據庫,那么,系統中就需呀SqlServerDAL和AccessDAL兩個數據訪問層,它們都含有一個數據訪問類,分別是SqlServerUsersDAL(對應本文實例工程BookStoreDAL中SqlServer文件夾下的Users)和AccessUsersDAL(對應本文實例工程BookStoreDAL中Access文件夾下的Users)。此時,用戶的業務邏輯層類UsersBLL(對應本文實例工程BookStoreBLL中的Users)作為客戶類,不應該與具體的數據訪問層類耦合,而應該先定義接口IUsersDAL(對應本文實例工程BookStoreiDAL中的IUsers)接口,讓業務邏輯層與這個接口耦合。再設計SqlServerDALFactory與AccessDALFactory,分別作為生成兩種數據訪問層的工廠,最后通過配置信息,決定在業務邏輯層中實例化哪個工廠。圖4.3抽象工廠模式在三層架構中的應用4.3三層架構中的外觀模式(Facade) 外觀模式(Facade)為子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用[1]圖4.4外觀模式(Facade)結構圖圖4.2是Facade模式的示意圖。在設計初期階段,應該要有意識的講不同的兩個層分離。經典的三層架構,就需要考慮在數據訪問層、業務邏輯層和表示層的層與層之間建立外觀Facade,這樣可以為復雜的子系統提供一個簡單的接口,使得耦合大大降低。致感指導老師對我的關心、鼓勵與幫助;感同學三、四和王五的熱情支持和真誠幫助;感家人在十幾年的求學生涯中,給予的教導、愛護與支持,促使我在人生的道路上不斷奮力前行。由于自身知識的不足,文中必存在不少疏漏和不足。敬請老師提出寶貴的意見,并衷心感。[參考文獻][1]ErichGamm,RichardHelm,RalphJohnson,JohnVlissides.設計模式:可復用面向對象軟件的基礎[M].:機械工業,2007.[2]RobertC.Martin.敏捷軟件開發:原則、模式與實踐[M].:清華大學,2003.[3]閻宏.Java與模式[M].:電子工業,2002.[4]MartinFowler.企業應用架構模式[M].:機械工業,2010.[5]甄鐳..NET與設計模式[M].:電子工業,2005.[6]程杰.大話設計模式[M].:清華大學,2007.[7]CSDN,.[8]博客園,.cnblogs.[9]Google,.google.[10]百度,.baidu.附錄一:代碼摘要用戶實體類:BookStoreModels.Users.csusingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceBookStoreModels{[Serializable()]publicclassUsers{publicUsers(){}privateintid=0;///<summary>///Id///</summary>publicintId{get{returnid;}set{id=value;}}privatestringloginId=String.Empty;///<summary>///用戶Id///</summary>publicstringLoginId{get{returnloginId;}set{loginId=value;}}privatestringloginPwd=String.Empty;///<summary>///用戶密碼///</summary>publicstringLoginPwd{get{returnloginPwd;}set{loginPwd=value;}}privatestringname=String.Empty;///<summary>///用戶名字///</summary>publicstringName{get{returnname;}set{name=value;}}privatestringaddress=String.Empty;///<summary>///用戶地址///</summary>publicstringAddress{get{returnaddress;}set{address=value;}}privatestringphone=String.Empty;///<summary>///用戶///</summary>publicstringPhone{get{returnphone;}set{phone=value;}}privatestringmail=String.Empty;///<summary>///用戶///</summary>publicstringMail{get{returnmail;}set{mail=value;}}privateintuserRoleId=0;///<summary>///用戶角色///</summary>publicintUserRoleId{get{returnuserRoleId;}set{userRoleId=value;}}privateintuserStateId=0;///<summary>///用戶狀態///</summary>publicintUserStateId{get{returnuserStateId;}set{userStateId=value;}}}}用戶數據訪問層接口:BookStoreIDAL.IUsers.csusingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceBookStoreIDAL{publicinterfaceIUsers{///<summary>///獲取用戶信息///</summary>///<paramname="_LoginId">用戶登錄賬號</param>///<paramname="_UserRole">用戶角色0為普通會員1為系統管理員</param>///<returns>返回用戶信息</returns>BookStoreModels.UsersGetModel(string_LoginId,int_UserRole);///<summary>///獲取用戶信息///</summary>///<paramname="_UserId">用戶ID</param>///<paramname="_UserRole">用戶角色0為普通會員1為系統管理員</param>///<returns>返回用戶信息</returns>BookStoreModels.UsersGetModel(int_UserId);/////<summary>/////獲取用戶信息/////</summary>/////<paramname="_UserId">用戶登錄賬號</param>/////<returns>返回用戶信息</returns>//BookStoreModels.UsersGetModel(int_UserId);///<summary>///獲取全部用戶///</summary>///<returns></returns>List<BookStoreModels.Users>GetModelList();///<summary>///獲取特定用戶///</summary>///<returns></returns>List<BookStoreModels.Users>GetModelList(intuserState);///<summary>///添加用戶///</summary>///<paramname="_User"></param>///<returns>添加成功放回true添加失敗返回false</returns>boolAddUser(BookStoreModels.Users_User);///<summary>///刪除用戶///</summary>///<paramname="_User"></param>///<returns>添加成功放回true添加失敗返回false</returns>boolDeleteUser(intId);///<summary>///更新用戶信息///</summary>///<paramname="_User">用戶的屬性</param>///<returns>修改成功放回true修改失敗返回false</returns>boolUpdateUser(BookStoreModels.Users_User);///<summary>///修改用戶密碼///</summary>///<paramname="_User">用戶的屬性</param>///<returns>修改成功放回true修改失敗返回false</returns>boolUpdatePwd(BookStoreModels.Users_User);///<summary>///修改用戶狀態///</summary>///<paramname="_UserStateId">用戶的狀態</param>///<returns>修改成功放回true修改失敗返回false</returns>boolUpdateUserState(int_UserStateId,int_Id);///<summary>///判斷是否存在此用戶///</summary>///<paramname="_LoginId">用戶名</param>///<returns></returns>boolIsExist(string_LoginId);///<summary>///判斷是否存在此類型用戶///</summary>///<paramname="_UserRoleId">用戶類型</param>///<returns></returns>boolIsExistSpecialUser(int_UserStateId);}}用戶業務邏輯層接口:BookStoreBLL.Users.csusingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingBookStoreDALFactory;usingBookStoreIDAL;namespaceBookStoreBLL{publicclassUsers{privatestaticAbstractDALFactory_BookStoreFactory=AbstractDALFactory.DALFactory();privatestaticIUsers_User=_BookStoreFactory.CreateUsers();//直接得到實際的數據庫訪問實例publicstaticBookStoreModels.UsersGetModel(stringloginId,intuserRole){return_User.GetModel(loginId,userRole);}publicstaticBookStoreModels.UsersGetModel(int_UserId){return_User.GetModel(_UserId);}publicstaticList<BookStoreModels.Users>GetModelList(){return_User.GetModelList();}publicstaticList<BookStoreModels.Users>GetModelList(intuserState){return_User.GetModelList(userState);}///<summary>///添加用戶///</summary>///<paramname="_User"></param>///<returns>添加成功放回true添加失敗返回false</returns>publicstaticboolAddUser(BookStoreModels.Users_UserModel){return_User.AddUser(_UserModel);}///<summary>//
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 私人健康財富管理制度
- 廣西玉林市八校2024-2025學年高一下學期4月期中聯合調研測試歷史試卷(含答案)
- 監理廉政責任管理制度
- 禁毒網絡平臺管理制度
- 金融行業數字化轉型中的風險管理與金融科技風險管理挑戰與機遇分析報告
- 2025年廣西南寧市中考歷史金考卷(含答案)
- 工地會議室管理制度
- 考研寄宿暑假管理制度
- 屠宰廠規章管理制度
- 組織層級動態管理制度
- 暑假提升部編版小學語文四升五暑假閱讀提升之概括文章中心思想 課件
- 低壓電工證考試試題及答案
- 2025深圳語文中考作文(10篇)
- 2025年大學生學術研究洞察報告
- 2025年廣東中考化學模擬演練化學試卷B(含答案)
- 2025春學期三年級語文下冊教學工作總結 (三篇)
- 2025聊城市輔警考試試卷真題
- 2025年全國二卷數學高考真題文字版
- 成都香城悅動置業有限公司招聘考試真題2024
- 2025年成都市初中學業水平考試道德與法治試題(含答案)
- 浙江省寧波2025年八年級下學期期末數學試題及答案
評論
0/150
提交評論