代碼大全 code complete閱讀筆記-3 第十四章 代碼的結構(順序與無序)

組織直線型代碼

我對這句話的理解是:要讓你的代碼符合人的閱讀習慣——由上到下。
代碼不應該只是純粹爲了通過編譯而寫,更重要的是要讓人更容易讀懂,這也是編程的藝術,如果所有代碼的目的都僅僅是通過編譯可以運行就行,那編程還有什麼藝術感美感可言,這裏粗略的將代碼分爲以下兩類:

  1. 必須有明確順序的語句
  2. 順序無關的語句

1.必須有明確順序的語句

當語句之間有依賴關係時,後一語句的執行必須依賴前一語句的結果
(下面所提的子程序可以理解爲方法或者某一可執行模塊)

data = ReadData();
results = CalculateResultsFromData();
PrintResults(result);

這段代碼就能看出前後之間的依賴性,也就是它們非按這個順序運行不可。
如果語句之間存在這樣的關係,那麼就一定要儘可能將它們這種關係明顯清晰地表達出來,這樣更有利程序的可讀性,接下來是相應的一些組織代碼的原則:

  1. 使依賴關係變得明顯
    要點在於使語句的功能儘量精簡而明確,每一個子程序應該有自己明確的處理任務,比如計算方法就不應該讓它承擔變量初始化的工作,並且這樣做更有利於爲子程序起名,因爲ComputeXxxxAndInitiatialXxxxx() 終歸是太長了,不如分爲兩行ComputeXxxx()InitatialXxxxx()
    這樣做雖然更麻煩,但是卻更靈活更清晰,你不僅一眼可以看出兩個動作的先後順序,更可以自由的在兩個動作之間再加入新的動作。

  2. 使子程序名能凸顯依賴關係
    如之前所說,一個子程序不應該做它自己名字內容以外的事,否則它就是一個糟糕的子程序。

  3. 使子程序參數明確顯示依賴關係
    上面的代碼就是一個很好的例子。

4.使用狀態變量或者錯誤處理碼

它還有一個更高大上的名字——內務管理變量 (housekeeping variables)
這裏加粗是因爲這對我來說是一個新事物,當然這也是十分重量的做法,一般用於十分重要的類或者方法中,當然不建議到處濫用。
例如:

class DataOperation{
	boolean isDataPrepared;
	//準備就緒
	void getPrepared(){
		isDataprepared = true;
	};
	void addData(){
		if(this.isDataPrepared==true){
			//如果爲true,方可執行
		}else{
		return;
		}
	}
}

在一個類中添加一個布爾成員變量isDataPrepared,並在構造器中將其初始化爲false,j假設增刪改查方法在執行前必須檢查isDataPrepared變量,若爲true方可執行,如此必然可以得出getPrepare()方法必須優先得到執行,否則後續無法操作。

當然這樣做的是有風險的,因爲它引入了更多的變量,修改了構造器,並且你必須要爲其編寫出錯代碼,所以我們需要在它的利弊之間權衡。

  1. 使用註釋來對不清晰的依賴關係進行說明
    這就是最下策了,當你的程序不允許你對它進行結構上的調整時,那你就只能用註釋加以說明了。我們更應該依賴上面的方法而不是依賴於註釋。

2.順序無關的語句

就近原則(Principle of Proximity):把相關操作放在一起。

十分好理解了,相關操作指同一個對象的方法,同一個類的方法等應該放在一起,而不是不同的方法穿插在一起。
這裏畫一個圖來生動表示:
在這裏插入圖片描述

這樣做的好處是:

  1. 儘可能縮小對象的存活(alive)行數。
    明明兩個方法可以連續執行完後就不需要引用方法的對象了,那就沒必要在兩個方法之間摻雜其他操作。儘量減少對象閒置無操作的代碼行數,這樣的好處是使程序更加清爽,一定程度提高了程序的性能。
  2. 使代碼易於自上而下的閱讀。

要點 key point

  • 組織線性代碼的最主要原則是按照依賴關係進行排列
  • 可以用好的子程序名、參數列表、註釋,以及——如果代碼足夠重要——內務管理變量可以讓依賴關係表現的更加明顯
  • 如果代碼之間沒有順序依賴關係,那就設法使相關的語句儘可能接近
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章