您的位置:軟件測(cè)試 > 軟件項(xiàng)目管理 > 項(xiàng)目案例分析 >
實(shí)戰(zhàn)項(xiàng)目分析
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/7/19 15:14:57 ] 推薦標(biāo)簽:

近接到一個(gè)臨時(shí)任務(wù):幫外國(guó)某知名公司分析一個(gè)項(xiàng)目架構(gòu)。這個(gè)項(xiàng)目是兩年前開(kāi)發(fā)的,并且經(jīng)過(guò)了幾次升級(jí)。主要功能是管理客戶、合作伙伴資料,提供在線業(yè)務(wù)等等,具體細(xì)節(jié)不用多說(shuō)。

據(jù)客戶說(shuō),他們?cè)谑褂帽鞠到y(tǒng)的過(guò)程中發(fā)現(xiàn)了很多的問(wèn)題,覺(jué)得已經(jīng)不再滿足他們的需求,希望我們能幫助他們?cè)u(píng)估一下當(dāng)前的系統(tǒng)有哪些架構(gòu)上的問(wèn)題,并幫助他們發(fā)現(xiàn)未來(lái)可能發(fā)生的問(wèn)題,從而決定是否需要開(kāi)發(fā)新的系統(tǒng)

客戶提供了很詳細(xì)的文檔,包括業(yè)務(wù)說(shuō)明,系統(tǒng)架構(gòu),技術(shù)要點(diǎn),部署方案等等?赐晡臋n,對(duì)系統(tǒng)和客戶期望有了一定的了解之后,開(kāi)始干活兒!

系統(tǒng)是采用.Net技術(shù)構(gòu)建的,基于.Net Framework 2.0,使用了ASP.NET, WinForm, WebService等技術(shù),并使用了Enterprise Library中的Data Access, Cache,Log等功能。

我本人負(fù)責(zé)的是架構(gòu)的分析。結(jié)合文檔和源代碼,沒(méi)用1個(gè)小時(shí),系統(tǒng)架構(gòu)很清晰了。其中發(fā)現(xiàn)了一些很普遍的問(wèn)題,在這里跟大家分享一下:

1. 分層架構(gòu)

分層架構(gòu)是絕大部分企業(yè)軟件都普遍采用的方案,但由于架構(gòu)師水平的參差不齊,導(dǎo)致很簡(jiǎn)單的一個(gè)分層,出現(xiàn)了很大的差異。

大家都知道“3層架構(gòu)”或者“多層架構(gòu)”。有點(diǎn)理論里分3層,有點(diǎn)理論里分5層,還有分7層的。其實(shí),在我看來(lái)分幾層不重要,重要的是分層的目的。分層是為了什么的?簡(jiǎn)單的說(shuō)一句話:為了便于維護(hù)。

大家都知道,軟件開(kāi)發(fā)中“變化”才是永恒的。開(kāi)發(fā)周期是死的(盡管可以一拖再拖,但總有一個(gè)發(fā)布的截至日期吧。,但后期的維護(hù)卻是很不變得。不管是發(fā)布補(bǔ)丁也好,更新版本也好,其實(shí)都是為了能適應(yīng)軟件發(fā)布之后面臨的各種各樣的“變化”。

好,我們回到分層上來(lái)。分層,是為了使系統(tǒng)結(jié)構(gòu)更清晰,系統(tǒng)耦合性變小,使修改一處代碼時(shí),對(duì)其它的部分影響小,這樣能以小的代價(jià)應(yīng)對(duì)變化帶來(lái)的麻煩!所以,分層的第一要素,是各層之間屏蔽細(xì)節(jié),降低依賴,使各層具體實(shí)現(xiàn)變得透明(這也是SOA的其中一個(gè)重要思想)。我們可以通過(guò)各種辦法來(lái)達(dá)到這個(gè)目的,面向接口編程,設(shè)計(jì)模式,架構(gòu)模式等等,都可以幫助我們。

而我在此項(xiàng)目中看到的第一個(gè)重要的問(wèn)題是,系統(tǒng)分層不清楚。下面是分層的簡(jiǎn)圖:

由上圖可見(jiàn),系統(tǒng)共分了 三層。但有一個(gè)問(wèn)題,業(yè)務(wù)對(duì)象竟然貫穿了三層,這嚴(yán)重違反了分層的初衷。由于業(yè)務(wù)對(duì)象對(duì)數(shù)據(jù)存取層和展現(xiàn)層都可見(jiàn),導(dǎo)致如果我們的業(yè)務(wù)對(duì)象發(fā)生了變化, 要修改從數(shù)據(jù)存取、業(yè)務(wù)邏輯到展現(xiàn)層,這三個(gè)層次的所有相關(guān)代碼。而且這個(gè)方案違反了分層的兩個(gè)設(shè)計(jì)原則:

a. 下層對(duì)上層隱藏細(xì)節(jié),只暴露接口。再此,本應(yīng)屬于業(yè)務(wù)邏輯層的業(yè)務(wù)對(duì)象被暴露到了展現(xiàn)層。

b. 上層對(duì)下層不可見(jiàn)。即下層不知道上層的存在,只提供接口。這里業(yè)務(wù)邏輯層的業(yè)務(wù)對(duì)象被數(shù)據(jù)存取層操作,會(huì)導(dǎo)致兩個(gè)層之間糾纏不清,以至于會(huì)出現(xiàn)改動(dòng)業(yè)務(wù)邏輯會(huì)影響數(shù)據(jù)存取方式的荒謬現(xiàn)象。

另外,強(qiáng)類型DataSet也有同樣的問(wèn)題(本應(yīng)是屬于數(shù)據(jù)存取層的,卻被傳遞到業(yè)務(wù)邏輯層,甚至是展現(xiàn)層)

軟件設(shè)計(jì)中有一個(gè)很重要的原則是:依賴倒置原則(DIP)

依賴倒置的意思是:調(diào)用者依賴被調(diào)用者的接口,而不是實(shí)現(xiàn)。

具體到此處是:業(yè)務(wù)邏輯層應(yīng)該依賴數(shù)據(jù)存取層的接口,而不是具體實(shí)現(xiàn)(強(qiáng)類型DataSet)。由于被調(diào)用者編程了抽象,而調(diào)用者變成了“實(shí)現(xiàn)”,所以與普通的面向?qū)ο蟮挠^念來(lái)說(shuō),依賴關(guān)系被倒置了,因此被稱作依賴倒置原則。

依賴倒置在分層結(jié)構(gòu)中是很重要的原則。希望每一個(gè)設(shè)計(jì)者都時(shí)刻把它記在心間吧,呵呵。

2. 面向接口編程

其實(shí)這跟上一個(gè)問(wèn)題有密切聯(lián)系。面向接口編程,是“依賴于抽象,而不是實(shí)現(xiàn)”的具體手段。不管是模塊內(nèi)部,還是個(gè)層次之間,面向接口是消除依賴的基礎(chǔ)。

舉一個(gè)簡(jiǎn)單的例子:本系統(tǒng)中業(yè)務(wù)邏輯層會(huì)調(diào)用數(shù)據(jù)存取層的方法,得到一些數(shù)據(jù)。比如調(diào)用一個(gè)PartnerAccess類的GetPartner的方法。PartnerAccess是數(shù)據(jù)存取層的一個(gè)具體類,負(fù)責(zé)Patrner表的所有增刪改查操作。而業(yè)務(wù)邏輯層到處充斥著這樣的語(yǔ)法:PartnerAccess partnerac = new PartnerAccess();partnerac.getPartner();

這是一個(gè)典型的依賴于具體實(shí)現(xiàn)的方案。這樣的后果是,業(yè)務(wù)邏輯層知道每一個(gè)數(shù)據(jù)表的數(shù)據(jù)結(jié)構(gòu),甚至是無(wú)需知道的細(xì)節(jié),并且對(duì)數(shù)據(jù)層的每一個(gè)方法都了如指掌,到處都在使用。當(dāng)我們開(kāi)始修改PartnerAccess的其中一個(gè)方法的時(shí)候(比如增加一個(gè)參數(shù))都要修改業(yè)務(wù)邏輯層的相關(guān)代碼,但誰(shuí)知道那些代碼都在哪呢?只好重新編譯吧,讓編譯器告訴我們。

上一頁(yè)123下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd