NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究_第1頁(yè)
NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究_第2頁(yè)
NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究_第3頁(yè)
NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究_第4頁(yè)
NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究_第5頁(yè)
已閱讀5頁(yè),還剩36頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

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

最新文檔

評(píng)論

0/150

提交評(píng)論