三個(gè)月沒(méi)寫(xiě)日志了,比較懶散……下半年準(zhǔn)備做OEA 的 B/S 版本,比較復(fù)雜,需要從架構(gòu)設(shè)計(jì)開(kāi)始認(rèn)真入手。正好今天到了部門(mén)反思的時(shí)間,今天先把原來(lái)的一些設(shè)計(jì)經(jīng)驗(yàn)總結(jié)一下,以方便將來(lái)回顧。 直入主題,這篇日志主要用于總結(jié)一些框架級(jí)別的模塊設(shè)計(jì)經(jīng)驗(yàn)。
總述
一個(gè)大型的框架,必然由多個(gè)較獨(dú)立的子系統(tǒng)/子模塊構(gòu)成。這些子模塊如何交互,之間的接口如何定義,這是框架的架構(gòu)設(shè)計(jì)的問(wèn)題。而今天我主要要總結(jié)一下,針對(duì)其中的某一個(gè)子模塊,應(yīng)該如何進(jìn)行設(shè)計(jì)。(例如,在 OEA 中有這些相對(duì)獨(dú)立的模塊:分布式框架、實(shí)體框架、界面生成框架、命令框架、產(chǎn)品線框架、分布式緩存框架、報(bào)表模塊……) 我在對(duì)一個(gè)模塊進(jìn)行設(shè)計(jì)時(shí),大致經(jīng)過(guò)以下流程:預(yù)設(shè)計(jì)階段、邏輯設(shè)計(jì)階段、設(shè)計(jì)評(píng)審、設(shè)計(jì)調(diào)整階段、設(shè)計(jì)實(shí)現(xiàn)階段、模塊整合階段。在一次單獨(dú)的設(shè)計(jì)中,并不是必須要經(jīng)過(guò)以上每一個(gè)階段。例如,當(dāng)模塊比較簡(jiǎn)單時(shí),就不需要設(shè)計(jì)評(píng)審、設(shè)計(jì)調(diào)整等階段了。以下我逐一描述。
預(yù)設(shè)計(jì)階段
設(shè)計(jì)開(kāi)始之前,我們需要為設(shè)計(jì)做很多工作。其主要的目標(biāo)是收集并整理模塊的需求,力求結(jié)構(gòu)化地描述需求。這些需求主要包括:場(chǎng)景需求、質(zhì)量屬性要求、環(huán)境約束。這個(gè)過(guò)程對(duì)于之后的設(shè)計(jì)過(guò)程相當(dāng)重要,原因也很明顯,不再贅述。 場(chǎng)景需求包括:框架用戶對(duì)模塊的功能性需求、70%場(chǎng)景、20%場(chǎng)景、10%場(chǎng)景、API 需求。 質(zhì)量屬性:參考ISO 9126。這里要分析出關(guān)鍵質(zhì)量屬性。 環(huán)境約束:技術(shù)約束、系統(tǒng)環(huán)境等。比較常見(jiàn)的是對(duì)原有系統(tǒng)的兼容性。 根據(jù)模塊的復(fù)雜度不同,這個(gè)階段的時(shí)間長(zhǎng)短可能會(huì)有很大區(qū)別。例如,界面生成框架在 OEA 框架中是核心模塊,在它的 2.0 版本的設(shè)計(jì)之前,我們平時(shí)會(huì)不斷地收集前一版本的缺點(diǎn)及不足,做整理并使這些雜亂的需求結(jié)構(gòu)化,這個(gè)工作“非正式”地做了一年,這些時(shí)間都可以算是在預(yù)設(shè)計(jì)階段中。 最后的交付物自然是:《模塊需求規(guī)格說(shuō)明書(shū)》。當(dāng)然,文檔這東西,主要用于溝通、傳授??梢钥辞闆r而定,不一定有這個(gè)必要。但是,如果后面有正式的評(píng)審會(huì)議,這個(gè)文檔最好還是準(zhǔn)備一個(gè)正式的。
邏輯設(shè)計(jì)階段 關(guān)鍵點(diǎn):場(chǎng)景驅(qū)動(dòng)設(shè)計(jì)、質(zhì)量屬性驗(yàn)證設(shè)計(jì)、環(huán)境約束驗(yàn)證設(shè)計(jì)。前者做加法,后兩者做減法。 設(shè)計(jì)師的經(jīng)驗(yàn)越豐富,在這個(gè)階段成功的機(jī)會(huì)也就越大。要滿足一套關(guān)鍵質(zhì)量屬性,如果你之前沒(méi)有遇到過(guò)類似問(wèn)題的話,可能你覺(jué)得你的設(shè)計(jì)能實(shí)現(xiàn),但是最后的事實(shí)往往不一定正確。而且設(shè)計(jì)不象數(shù)學(xué)那么嚴(yán)格,更象是藝術(shù),藝術(shù)靠什么,靈感!所以這個(gè)階段中,不同的設(shè)計(jì)師很可能會(huì)有不同的設(shè)計(jì)稿。(當(dāng)然,如果這個(gè)模塊比較簡(jiǎn)單的話,很可能設(shè)計(jì)就不會(huì)有什么區(qū)別了,畢竟,現(xiàn)有的軟件設(shè)計(jì)的模式是很多的。) 邏輯設(shè)計(jì)的方法主要還是畫(huà)圖。其中主要還是依據(jù)一些通用設(shè)計(jì)的原則進(jìn)行設(shè)計(jì)。 畫(huà)什么?主要是 UML 中的兩類圖:靜態(tài)結(jié)構(gòu)圖(包圖、類圖);動(dòng)態(tài)結(jié)構(gòu)圖(序列圖)。 順帶說(shuō)一句,很多設(shè)計(jì)人員可能會(huì)坐在電腦旁邊直接拿 EA 等工具畫(huà)圖。但是我個(gè)人比較喜歡的方式是:
交付物:UML 圖!這是必須的! 這個(gè)階段中,主要考慮質(zhì)量屬性及關(guān)鍵需求。 要提升該階段的能力,個(gè)人再次推薦幾本著名的書(shū)籍:《Pattern of Enterprise Application Architecture》,《Microsoft Application Architecture Guide》,《Enterprise Solution Patterns Using Microsoft .NET》。
設(shè)計(jì)評(píng)審 召開(kāi)設(shè)計(jì)評(píng)審會(huì)議的原因:
所以,如果不是十萬(wàn)火急,都建議召開(kāi)評(píng)審會(huì)議! 我主持過(guò)的評(píng)審會(huì)議,曾經(jīng)出現(xiàn)了許多的問(wèn)題,大家可以看看我當(dāng)時(shí)的反思:《反思 - 組內(nèi)設(shè)計(jì)評(píng)審會(huì)議》,不要出現(xiàn)和我一樣的錯(cuò)誤。
設(shè)計(jì)調(diào)整階段 沒(méi)啥,看評(píng)審會(huì)議的結(jié)論。要么做些小的調(diào)整,要么大改動(dòng),甚至重新設(shè)計(jì)。如果改動(dòng)較大,別忘了最后再召開(kāi)一次評(píng)審會(huì)議。
設(shè)計(jì)實(shí)現(xiàn)階段 這個(gè)階段包含了設(shè)計(jì)的代碼驗(yàn)證階段。 可能由于公司的組織結(jié)構(gòu)不同,這個(gè)階段并不一定由設(shè)計(jì)師自己去完成。但是我建議不要完全由他人完成,設(shè)計(jì)就象是自己的孩子一樣,辛苦辛苦把他生下來(lái),你讓別人來(lái)把它撫養(yǎng)大,不覺(jué)得奇怪嗎?如果你覺(jué)得你要設(shè)計(jì)的東西太多,沒(méi)時(shí)間完成,我覺(jué)得你還是少做一些,做好一些會(huì)更好。 建議實(shí)戰(zhàn)能力弱甚至沒(méi)有實(shí)戰(zhàn)能力的設(shè)計(jì)人員不要再做設(shè)計(jì)了,先好好在底層磨煉磨煉吧。設(shè)計(jì)師從程序員成長(zhǎng)而來(lái),架構(gòu)師從設(shè)計(jì)師成長(zhǎng)而來(lái),這才是務(wù)實(shí)的做法! 這個(gè)階段考驗(yàn)的是設(shè)計(jì)人員的代碼實(shí)現(xiàn)能力,團(tuán)隊(duì)協(xié)作能力。代碼的實(shí)現(xiàn)能力往往真正能看出一個(gè)人的設(shè)計(jì)能力。軟件設(shè)計(jì)原則大家都會(huì)說(shuō),但是,要真正把這些原則應(yīng)用到代碼實(shí)現(xiàn)中,卻需要時(shí)間的不斷磨煉。如果開(kāi)發(fā)組里能有幾個(gè)為技術(shù)癡迷的人,那是最好不過(guò)的了。 實(shí)現(xiàn)相對(duì)于設(shè)計(jì)稿,可以有一些更多的靈活性,并不一定要100%符合設(shè)計(jì)稿,這是因?yàn)榇a實(shí)現(xiàn)本身就是一種微觀的設(shè)計(jì)。但是必須要求80%以上是要符合設(shè)計(jì)稿的。如果實(shí)現(xiàn)過(guò)程中,不得已有過(guò)多的部分不符合當(dāng)初的設(shè)計(jì)稿。請(qǐng):召開(kāi)討論會(huì)議!重新畫(huà)圖描述當(dāng)前設(shè)計(jì)!總結(jié)反思! 值得一說(shuō)的是,實(shí)現(xiàn)階段需要著重對(duì)使用場(chǎng)景進(jìn)行 721 分析,設(shè)計(jì)良好的 API 以應(yīng)對(duì)這些場(chǎng)景,并配以相應(yīng)的單元檢測(cè)。關(guān)于框架設(shè)計(jì)中的場(chǎng)景驅(qū)動(dòng)設(shè)計(jì),大家可以看這篇文章推薦的書(shū)籍:《Framework Design Guidelines 2nd Edition》。
模塊整合階段 其實(shí)這個(gè)階段中的工作在上一階段中需要準(zhǔn)備好,也就是說(shuō),在進(jìn)行編碼時(shí),需要不斷考慮所設(shè)計(jì)的代碼能否在大的環(huán)境中運(yùn)行。所設(shè)計(jì)的接口是否能和當(dāng)前系統(tǒng)正確的銜接上。如果之前的代碼沒(méi)有考慮足夠,在這一整合階段中,可能會(huì)發(fā)生一些集成的問(wèn)題。不過(guò)這種情況我遇到的比較少,這里就不展開(kāi)了。 這階段完成后,最好能配上集成測(cè)試。(不過(guò)我目前都沒(méi)有做過(guò)。)
演進(jìn)模塊的考慮點(diǎn)
在整個(gè)框架的架構(gòu)設(shè)計(jì)完成之后,其中所涉及到的模塊分兩類:一類是在架構(gòu)設(shè)計(jì)時(shí)已經(jīng)考慮到并明確定義的模塊;另一類是架構(gòu)初始設(shè)計(jì)時(shí)并沒(méi)有考慮到,但是隨著系統(tǒng)逐漸演進(jìn),發(fā)現(xiàn)必須被添加進(jìn)來(lái)的模塊,我簡(jiǎn)稱其為“演進(jìn)模塊”。兩種模塊的設(shè)計(jì)有許多相同之處,相對(duì)而言,設(shè)計(jì)演進(jìn)模塊時(shí),相對(duì)要需要考慮更多的東西。 針對(duì)演進(jìn)模塊,在預(yù)設(shè)計(jì)階段,約束中需要重點(diǎn)寫(xiě)明歷史系統(tǒng)對(duì)當(dāng)前模塊的兼容性約束。在設(shè)計(jì)階段,需要分析當(dāng)前系統(tǒng),從中找到突破口。 兼容性是很麻煩的一種約束,為了滿足這種約束,常常會(huì)使簡(jiǎn)單的設(shè)計(jì)變得復(fù)雜。最后的代碼也很可能寫(xiě)得不符合規(guī)范。在以后的新版本中,如果做出不再兼容這些歷史代碼的決定時(shí),這些兼容性設(shè)計(jì)需要被刪除。
設(shè)計(jì)失敗的常見(jiàn)原因
總結(jié)
這篇文章是基于目前我的設(shè)計(jì)經(jīng)驗(yàn)總結(jié)而成,將來(lái)可能會(huì)不斷更新…… 同時(shí),希望和園友們交流設(shè)計(jì)經(jīng)驗(yàn)。更加希望平臺(tái)開(kāi)發(fā)人員能和我一起交流平臺(tái)級(jí)別的開(kāi)發(fā)。 可以短信我,交換QQ和EMail。 |
|