本篇寫于讀<Code Complete>之后,面對(duì)實(shí)際設(shè)計(jì)中的問題時(shí)產(chǎn)生的一些感悟,在這里和大家一起分享。。
第一頁
設(shè)計(jì)是個(gè)“鬼”命題。為什么呢?它又鬼在哪呢?
A
wicked problem as one that could be clearly defined only by solving
it or by solving part of it.
---Horst
Rittel and Melvin Webber
這里是大師的定義。只有你解決了或者部分解決這個(gè)問題的時(shí)候,你才能清楚的定義它。
用白話講,只有你做了,你才知道它是怎么回事,怎么才能做好這件事。
所以,我常常拿到一個(gè)開發(fā)功能而又無從下手時(shí),除了尋找支援,詢問別人,唯一剩下的路就是嘗試著去做。雖然是膽顫心驚、如履薄冰,但是做著做著就明白了。
我想,大師告訴我們這是一個(gè)鬼命題,第一,是告訴我們第一次摸著石頭過河是人類的認(rèn)知規(guī)律,開始時(shí)做錯(cuò)了是正常的;第二,就是讓我們勇敢的去嘗試。
第二頁
設(shè)計(jì)是一個(gè)迭代的過程。
大家先看這幅圖。

這里典型的瀑布式設(shè)計(jì)“分析==>設(shè)計(jì)==>編碼==>測試”。這個(gè)過程每一個(gè)階段都有明確的輸入/輸出,每個(gè)階段都有一個(gè)交付件。這對(duì)我們的管理者是個(gè)福音,因?yàn)檫@樣子,項(xiàng)目的進(jìn)展一目了然,項(xiàng)目就可控了。所以說,這個(gè)過程是為Mananger寫的。所以,有了這句話“Oh,
I write specs to keep managers happy and then code the thing the way
I want “
因?yàn)椋聦?shí)上,我們程序員感覺到的設(shè)計(jì)過程不是這樣的。而是這樣的:

同樣,它也是基于瀑布模型的。只是增加了一個(gè)逆向過程,使得我們?cè)谙乱浑A段發(fā)現(xiàn)問題時(shí),可以回過頭來修正。
我們現(xiàn)在來想想這個(gè)問題,為什么大家會(huì)說
“設(shè)計(jì)文檔沒有用”?因?yàn)樽鳛橐粋€(gè)過程的輸出結(jié)果,設(shè)計(jì)文檔有個(gè)致命的問題:無法保證文檔與代碼同步。表現(xiàn)在兩個(gè)方法:
1.無法保證設(shè)計(jì)文檔的結(jié)果一定會(huì)反映在代碼中(除了人去看,無法證實(shí))。
2.設(shè)計(jì)的成果,要通過重復(fù)勞動(dòng)在代碼中來表現(xiàn)。
3.后期代碼結(jié)構(gòu)的變化,很難表現(xiàn)在設(shè)計(jì)文檔中。
所以我說,設(shè)計(jì)階段的輸出應(yīng)該是一份Rose文檔和一份簡要的設(shè)計(jì)補(bǔ)充說明。這樣,我們用Rose的逆向工程能力來表現(xiàn)現(xiàn)有代碼的實(shí)際結(jié)構(gòu)/接口;用Rose的代碼生成能力來表現(xiàn)接口的修改。我們現(xiàn)在來試一下。
(Rose使用展示)
這樣,我們將模塊、類、類接口等都表現(xiàn)在Rose中,而將偽碼以注釋方式寫在代碼中。
我們少了多少事啊~~
這里附帶著強(qiáng)調(diào)一點(diǎn),里程碑很重要。沒有了里程碑,迭代的設(shè)計(jì)很就成了死循環(huán)。不可控的項(xiàng)目也不會(huì)是好項(xiàng)目。
第三頁
分而治之
這是人類解決復(fù)雜問題的通用解決方法。
對(duì)應(yīng)于我們軟件設(shè)計(jì)過程,就是“產(chǎn)品?模塊?類?方法”的逐層分解過程。
產(chǎn)品
|
0層
|
模塊與模塊/模塊與用戶的契約(public
方法)
|
模塊
|
1層
|
類之間契約(friend
方法)
|
類
|
2層
|
偽碼/私有方法
|
其中,模塊確定了與其它模塊之間、與用戶之間的契約(模塊間公共接口);類確定了類之間的契約(包內(nèi)公共接口);方法確定了私有方法。下一層總是服務(wù)于上一次。
這個(gè)過程通過Rose完全能夠完成。所以,設(shè)計(jì)階段不等于寫設(shè)計(jì)文檔。設(shè)計(jì)文檔僅僅是輸出結(jié)果。
第四頁
自上而下和自下而上
這是兩種不同的思考過程。自上而上是由抽象到具體,自下而上則相反,由具體到抽象。上面提到的,分而治之,逐層分解就是一種自上而下的過程。
一般來講,自上而下比較容易點(diǎn),也是軟件設(shè)計(jì)中比較提暢的一點(diǎn)。我們經(jīng)常強(qiáng)調(diào)的“依賴反轉(zhuǎn)”,依賴于抽象,而不是依賴于具體。都是自上而下的抽象分解過程。
那么,
在設(shè)計(jì)中還有一個(gè)關(guān)注點(diǎn)“分離變化點(diǎn)”。是我們隔離變化,將變更的影響降低的一種方法。這里就有個(gè)問題,如果你不再往下看,找出具體是什么會(huì)變化,你怎么將變化隔離封裝?這個(gè)時(shí)候,要的就是“自下而上”的分析。
佛教有一句“法無定法”,意思是說做好一件事,不一定有一個(gè)固定的法則。當(dāng)你用一種方法直不下去時(shí),不妨試試其它方法。所以,自上而下與自下而上并不矛盾。
第五頁
原型。
設(shè)計(jì)的時(shí)候,經(jīng)常有這樣一個(gè)問題。以前沒搞過,現(xiàn)在這么做行不行呢?心里沒底。那怎么辦?寫個(gè)原型。
就在代碼中寫。需要的時(shí)候,在進(jìn)入編碼階段時(shí),重復(fù)利用。
(比如這次我要開發(fā)個(gè)向?qū)В野l(fā)現(xiàn)有個(gè)現(xiàn)成的框架。但是不知道該怎么用,不知道能不能滿足需要。所以,我按照現(xiàn)在規(guī)格,寫了一點(diǎn)原型代碼。發(fā)現(xiàn)可以用。)
但是這里有個(gè)分寸的問題,就是不要寫的太多。能夠證實(shí)你的想法就可以了。一是因?yàn)樵蹅冞€有里程碑計(jì)劃,有時(shí)間點(diǎn)的壓力。二是因?yàn)椋@部分代碼只是試驗(yàn),并不可靠,寫的越多,隱藏的問題就會(huì)越多。
第六頁
設(shè)計(jì)到什么時(shí)候結(jié)束?
下列兩個(gè)條件中滿足任意一個(gè)結(jié)束:
-
你覺的再設(shè)計(jì)就成了寫代碼了;
-
你沒有時(shí)間了;
第一個(gè)結(jié)束點(diǎn),對(duì)各個(gè)人不一樣,只要你感覺你能寫出代碼了就行。所以,對(duì)于經(jīng)過多個(gè)版本的人可能會(huì)結(jié)束的早一些。
第二個(gè)結(jié)束點(diǎn),沒有辦法的事,無論好壞,認(rèn)命,趕快把文檔搞的貌似結(jié)束,在編碼階段再嘗試補(bǔ)救。
結(jié)束
posted on 2008-06-09 22:14
wukaichun 閱讀(956)
評(píng)論(0) 編輯 收藏 所屬分類:
design