很久以前就見過這本1000頁的書<代碼大全>,覺得應該是說些寫代碼的東西,沒怎么又興趣去讀它,一次偶然的機會,發現自己是誤解了它,<代碼大全>覺得應該叫軟件百科好像更合適一點,因為它里面涵蓋了架構,分析,設計,編程,測試,重構,面向對象,調試,規范,管理,軟件質量控制,協作,優化,開發工具,注釋,甚至個性,開發藝術等等等,讓人感覺就是一本軟件百科全書.
書讀的不多,不過剛開始讀了100多頁有一點感悟,所以做了一點記錄,叫讀<代碼大全>的一點記錄之1.
利用隱喻
隱喻通過把軟件開發與你所熟知的事情聯系在一起,從而使你對其更有深刻的理解,正是因為如此在計算機中的發展不過僅有數十年的歷史,卻擁有著所有科學最為豐富多彩的語言
蓋房子的隱喻
狗屋
霹靂啪啦,木材加鐵釘,犯錯了怎么辦?無所謂,拆了再來過
蓋一棟房子
決定什么類型的房子-->問題定義
和某個建筑師探討總體的設計-->軟件架構設計
畫出詳細的藍圖-->詳細設計
打地基,搭建房屋框架,砌墻,蓋好屋頂,同水,電,煤氣-->軟件構建(編程)
油漆工和裝修工把新蓋的家進行美化-->軟件的優化
監查人員來檢查工地,地基,布線-->軟件的復查
我們會發現很多軟件工程學的名稱就是從建筑學演變而來的如
軟件架構(建筑學 architecture)
支撐性測試代碼(腳手架,scaffolding)
構建(建設,construction)
基礎類(foundation classes)
摘錄
P70:使用隱喻又是件說不清楚的事情。你需要適當地引申它的含義,才能從其中蘊含的深刻啟發中受益。但若你過分地或者在錯誤的方向上引申了它的含義,它也會誤導你。正如人們會誤用任何強大的工具一樣,你也可能誤用隱喻,但它的強大的功效,還是會成為你智慧工具箱中的一個寶貴部分
兩條食物鏈
* 健康的生態環境中,海鷗吃新鮮的鮭魚,鮭魚吃新鮮的青魚,青魚吃新鮮的水蝽。這是一條健康的食物鏈。
* 軟件開發中,架構師吃掉需求,設計師吃掉架構,程序員,軟件食物鏈的最后一環,消化掉設計。
我們知道毒素是往上遞增的,如果在軟件開發中,從一開始就被污染了,那么每級的污染程度將遞增,而程序員在處在食物鏈的最高層,也是毒素累積的最高層,就必須抗下所有犯下的錯誤
需求的 checklist
我們是否一定要做需求checklist?書中作者告訴我們并不一定要寫需求分析樹,但需求分析必須在大腦中,口頭交流上完成,落下文字固然是好的,但并不是重點,關鍵在于做不做,一份checklist就想事一次"心智健全"的檢查,看看你的地基是否堅固
詳細的checklist包括是否詳細定義了系統的全部輸入,包括來源、精度、取值范圍、出現頻率。是否詳細定義了系統全部輸出,包括目的,精度,取值范圍、出現頻率,格式?是否定義了機器內存和剩余磁盤空間的最小值?是否詳細定義了系統的可維護性,包括適應特定功能的變更、操作環境的變更、與其他軟件的接口的變更能力?…..
構建高質量的子程序
書中作者用大篇幅去介紹如何構建高質量的子程序,在此章,作者用一個有問題的子程序羅列出他所指出的所有引發低質量子程序問題,我把以下的一個子程序認為是作者最好的總結
Procedure HandleStuff ( Var InputRec:CORP_DATA,CrntQtr:integer,
EmpRec:Emp_DATA, Var EstimRevenue:Real, YTDRevenue:Real,
ScreenX:integer,ScreenY:integer,Var NewColor:Color_TYPE,
Var PrevColor:COLOR_TYPE,Var Status:STATUS_TYPE,
ExpenseType:integer);
begin
for i := 1 to 100 do begin
InputRec.revenue[1]:= 0;
InputRec.expense[i]:=CorpExpensse[CrntQtr,i]
end;
UpdateCorpDatabase(EmpRec);
EstimRevenue:=YTDRevenue * 4.0 /real(CrntQtr)
NewColor:=PrevColor;
status:=Success;
if ExpenseType=1 then begin
for i:= 1 to 12 do
Profit[i]:= Revenue[i]-Expense.Type[i]
end
else If ExpneseType= 2 then begin
Peofit[i]:=Revenue[i] - Expense.Type2[i]
end
else if ExpenseType= 3 then
begin
Profit[i]:=Revenue[i] - Expense.Type3[i]
end
end
下面的問題囊括了作者在此章說明的問題
1.程序的名字讓人困惑。HandleStuff()能告訴我們程序是干什么的嗎?
2.程序沒有被說明
3.子程序的布局不好。代碼的物理組織形式幾乎沒有給出其邏輯組織形式的任何信息。
4.布局的使用過于隨心所欲,程序每一部分的布局都是不一樣的。關于這一點。只要比較一下 ExpenseType=2 和 ExpenseType=3 兩個地方的風格就清楚了
5.子程序的輸入變量值 InputRec 被改變過。如果它作為輸入變量,那它的值就不該變化。如果要變化它的值,就不該稱之為輸入變量 InputRec。
6.子程序進行了全局變量的讀寫操作。它從 CorpExpense中讀入變量并寫給 Profit。它應該與存取子程序通信,而不應直接讀寫全局變量。
7.這個子程序的功用不是單一的。它初始化了某些變量。對一個數據庫進行寫操作,又進行了某些計算工作,而它們又看不出任何聯系。一個子程序的功用應該是單一,明了的。
8.子程序中沒有采取預防非法數據的措施。如果 CrntQtr 的值為“0” ,那么,表達式YTDRevenue*4.0/real(CrntQtr)就會出現被零除的錯誤。
9.程序中使用了幾個常數:100, 4.0, 12, 2 和 3。關于“神秘”(magic)數的問題見 11.1節“常數”
10.在程序中僅使用了域的 CORP_DATA 型參數的兩個域。如果僅僅使用兩個域,那就該僅僅傳入特定的域而不是整個結構化變量。
11.子程序中的一些參數沒有使用過。ScreenX和 ScreenY在程序中沒有涉及。
12.程序中的一個參數被錯誤標定了。PrevColor被標定為變量型參數,然而在程序中又沒有對其賦值。
13.程序中的參數太多。程序中參數個數的合理上限應該是七個左右。而這個程序中則多達11個。程序中的參數多得怕人,恐怕沒誰會仔細檢查它們,甚至連數一下都不愿意。
高扇入 和 低扇出
摘錄
高內聚,低耦合很容易被重視。但是高扇入低扇出有時候會被忽略。這里是說,我們應該盡量的大量的使用某個低層次上給定的類(high fan-in) 而每個類都應該盡量少使用其他的類(控制在7個之下)。
小結
書中分別很詳細的寫了架構,設計,編程等等方面的內容,還不分巨細的討論了函數,變量,語句等編程要點,這些內容基本上都是圍繞著軟件構建的核心就是管理復雜度來展開的,產生這個根源就在于人腦智力同軟件項目復雜度的矛盾.
而解決這矛盾從作者書中總結可能有以下幾點:
1.分割
系統分割,設計分割,代碼分割....
2.清晰理解
抽象,封裝
3.清晰表達
----------------------------------------
by 陳于喆
QQ:34174409
Mail: dongbule@163.com