Ch6 工作類別
類別基礎:抽象資料型別(ADT)將字型大小變更為12點,即16個像素高
//易混淆 currentFont.size = 16; //不知是pixel還是點 //較具意義 currentFont.size = PointsToPixels(12); currentFont.bold = true; currentFont.setBoldOn();
Ch7 高品質常式
從常式名稱中可猜出其作用單一且明確定義的目的
參數不易超過7個,造成閱讀不易
具備抵禦錯誤資料,不會造成當機
良好的常式名稱
- 描述常式的所有工作
- 避免無意義、模糊式空泛的動詞命令
- 勿僅用數字后別常式名稱
- 用回傳值述命名函式
FormatAndPrintOut()會比HandleOutput()更加的清楚
part1(),part2()
printer.isReady(),user.next()
- 文件化有關參數的介面假設
- 考慮輸入、修改和輸出參數的命名慣例
不要回頭再寫註解,數字參考單位,預期值的範圍、永不應出現的特定值
input_,modify_,output_
Ch8 防禦性程式設計
用判斷提示證明和驗證前置條件及後置條件又稱為design by contract (Meyer 1997)
function velocity(float latitude, float longitude,float elevation){ //Preconditions Debug.Asert ( -90 <= latitude && latitude <= 90); Debug.Assert ( 0 <= longitude && longitude<= 360); Debug.Assert ( -500 <= elevation && elevation <= 75000); ... //Postcondition Debug.Assert()0 <= returnVelocity && returnVelocity <= 600); //return value return returnVelocity ; }
對於錯誤的條件,常式通常會用判斷提示或直接處理錯誤的程式碼
判斷提示
Debug.Assert()0 <= returnVelocity && returnVelocity <= 600);
直接處理錯誤的程式碼
... //cloest legal value if(latitude <-90) latitude = -90; else if (latitude > -90) latitude = 90; ...
8.3 處理錯誤的技巧
傳回中性值有時對錯誤資料的最佳反應就是持續操作,回傳預設值。數字計算=>0,文字操作=>空字串
關鍵情況下,就回傳錯誤,不要回傳錯誤的資料。
以下一個有效資料取代
處理資料串流時
傳回與上一次相同的回答
考慮建立集中的例外況報告程式
確保例外狀況處理一致性,也能提供中央儲存機制九
function reportException(string className, Exception ex){ string caption="Exception"; string message = "Exception: " + ex.Message + Enviroment.NewLine + "Class: " + className + Enviroment.NewLine + "Routine: " + ex.TargetSite.Name; MessageBox.Show(message,caption); } //example try{ ... }catch(Exception ex){ reportException(CLASSNAME,ex); }
8.5 建立路障,避免程式內含錯誤造成的損毀
撰寫驗證類別,在所有介面運算資料前,透過驗證類別確保資料有效
Ch14 組織直線
14.1.須依特定順序排列的陳述式
1.連續呼叫相依的methods
//計算年營收前,得先計算季營收,而計算季營收前,要先計算月營收 revenue.ComputeMonthly(); // revenue.ComputeQuarterly(); revenue.ComputeAnnual();
相依性不明顯,將來順序對換,會造成錯誤, 要讓程式碼可看出其相依關係2.初始化
//求各部門支出前,要先利用ComputeMarketingExpense()初始化
ComputeMarketingExpense(); //
ComputeSalesExpense();
ComputeTravelExpense();
無法在第一時間看出計算前要先初始化,將來順序對換會錯誤
使常式參數使相依性明顯
//利用初始化及輸出值,提示相依性 expenseData = InitializeExpenseData(expenseData); expenseData = ComputeMonthly(expenseData); expenseData = ComputeQuarterly(); expenseData = ComputeAnnual();
Ch15 使用條件式
15.1 if
指導方針
- 先寫pass判斷的正常路徑;再寫異常案例後,避免模糊掉執行邏輯
- 將正常的case置於if block, 而非else後方
OpenFile(inputFile, status); if( status = Status_Success ) //pass ReadFile( inputFile, fileData, status); //名目案例 if(status = Status_Success) { end(); errorType= ErrorType_None; } else errorType = ErrorType_FileReadError; //錯誤案例 else errorType = FileOpenError; //錯誤案例
重點在讀取主要流程,而非費力專研例外案例Ch26. 程式碼微調技巧
26.2 迴圈
決策外置(Unswitching)
如果if判斷不會在迴圈執行時變更,就把if搬到迴圈外
合併
將兩個相同集合項目的迴圈合併,一次就把兩次事做完
for(i=0;i<n;i++) a++; for(i=0;i < n;i++) b++; ------------------------合併成------------------------ for(i=0;i < n;i++){ a++; b++; }
減少迴圈內的工作
要使迴圈有效率,其中的關鍵在減少迴圈內部的工作。
如果可在外部運算部份或全部的陳述式,只讓結果進入迴圈內,就可提升效率
26.3 資料轉換
使用整數而非浮點數
盡量不要使用陣列維度
減少陣列參考
利用變數存陣列值,就可避免在迴圈內讀取陣列值
for(...) rate[level] *= discount[type]; //discount[type]可抽出來 ---------------------用變數取代--------------------------------- discounttype = discount[type]; for(...) rate[level] *= discounttype;
26.4 運算式
利用代數恆等式
not a and not b = not (a or b)
後者會比前者快上將近1份的時間
使用強度降代
- 用加法取代乘法
- 用乘法取代乘冪
- 用三角恆等式取代三角常式
- 整數運算會比浮點數快
- 使用位移運算取代整數乘除
沒有留言:
張貼留言