1. 程式人生 > 其它 >開發實踐思考(二)

開發實踐思考(二)

開發實踐思考第二篇。

本篇接上一篇《開發實踐思考(一)》,繼續將之前散落的思考點彙總,每篇10條。

1. 同層級的判斷只在當前層級生效,不能跨層級保證

舉一個簡單的例子:


bool Fun1(const char* pData)
{
	if (NULL == pData)
	{
		assert(0);
		return false;
	}

	// XXXXXX處理

	DetailFun(pData);
}

bool DetailFun(const char* pData)
{

}


提問,在DetailFun函式中,需不需要對pData再做非空判斷?
觀點A:外層呼叫者已經保證pData的有效性,DetailFun

內部無需再次處理。
觀點B:DetailFun函式內部對入參也要做有效性判斷,因為不能保證它被其他函式呼叫時,其他函式也做了同樣保證。

筆者的看法:同層級的判斷,只能保證同層級的有效性,一旦將資料傳給其他模組,合法性就交給其他模組來鑑別,而不要自身在多做一層判斷,如果有效就傳給其他模組,如果無效就不傳。

小結:每個函式只需要關注自身入參的有效性,要做到,無論在什麼環境,都不會因為外部入參的錯誤而導致自身出錯。

2. 不要被別人寫的程式碼誤導

別人寫的不一定是最好的,如果只是簡單的仿照繼承,那無助於成長。

在平時工作中,免不了維護舊程式碼。對舊程式碼有兩種態度:

態度1:舊程式碼跑了這麼舊,它這樣寫,猜測應該是有它的意圖,可能是應對某種特殊情況之類的吧,目前不知道,因此,新的實現照搬原來的寫法。

態度2:在仔細分析舊程式碼流程發現,原來的寫法是暫時性的解決方案,有一股“弄巧成拙”的碰巧感和“短平快”的緊急解決方案。

筆者的看法偏向於態度2,很多時候,面對問題,通常有兩種處理方向:

  1. “短平快”的解決方案,一般改動範圍小,加個else/case,加個虛擬函式重寫之類的,能遮蔽或繞過問題的觸發條件,使其緩解,但通常不優雅,加大耦合。

  2. “徹底的”的解決方案,從問題發生點逐層上推,直到問題根源,一路順著呼叫關係鏈條來徹底改正。同時,檢查工程中其他類似的地方,將同類型的問題一併解決掉。

這兩種處理方向都有各自的使用場景。從長遠來看,應儘量少一些特例、特殊處理,更多的是通用問題的通用方法。如果當時迫不得已那樣做,後續也要標記下,用更為通用、優雅的方法來解決。

3. 程式碼提交保持單一職責

每次提交只保證做一件事,提交的所有修改都聚焦於這件事。根據自己的經驗,可將程式碼提交按照目的分為以下三類:

  1. 改Bug
  2. 實現新功能
  3. 程式碼重構

在提交程式碼時,針對以上三類目的,要有明確區分,儘量不要混在一起提交。

有時候,場景1和3可以一併提交,但要限制重構範圍,重構與此Bug密切相關的地方,那些不相關的重構,不要混雜在一起。

4. 程式正確性問題

從測試的角度來說,要證明程式有問題,很簡單,構造各種場景,看實際輸出與預期輸出是否一致,只要不一致,那就說明程式是有問題的。

從開發的角度來說,如果想向別人證明,自己的程式是很少問題甚至是沒有問題,是非常難的。

因為從邏輯上來看,這個類似於有罪判定。預設情況下,人都是無罪的(類似於程式都是正確的),誰懷疑他有罪,誰就提供證據,將舉證責任交給提出假設的一方是慣例。

還有一點,從邏輯上說,證有不證無。你只能證明某一個人有罪,無法證明一個人無罪。

回到開發上看,開發自測時,只能儘可能測試所有能想到的可能場景,在已列出出的場景範圍內,可證明是沒問題的。測試要做的是窮舉儘可能多的場景,至於到底有多少個場景,有多少個路徑,每個人的經驗、看法不同,難以達成一致。

開發和測試能做到的,在自己能力範圍內,儘可能構造場景並發現錯誤,但無法杜絕問題的產生。

5. 列舉定義以及輔助函式定義在一起

定義列舉時,建議將對應的輔助抓換函式寫在一起,這樣的好處是減少後續新增定義時,忘記在轉換函式中新增對應入口造成的潛在的錯誤。

6. 顯式送參優於隱式

當介面文件中有這樣描述入參,“送空和送0是一樣效果”,那建議顯式的送0,而不是送空。這樣做有如下好處:

  1. 清晰直接
  2. 如果後續結構有新增入參,那麼之前的入參可以一一對應地上,而不靠著隱含的空字串

此條同樣適用於函式預設引數,筆者覺的,函式預設引數會加大呼叫者的心智負擔,在傳引數時,顯式送參優於預設引數,少用預設引數。

7. 謹慎處理特殊值

針對"0"、""、" "和"-1(無效值)"等特殊數值,在業務判斷中要特別處於,要明確區分上述情況下的處理。

8. 提交Bug時關聯類似Bug

在解決Bug時,如果感覺之前有解決過類似Bug,這種情況,可以在此Bug的備註中,註明與之關聯的Bug號,提醒測試在測試時注意下。

如果此BugA是因為修改另一個BugB導致的,那更需要在備註中,將BugB的改動導致BugA的修改簡要說明下,有助於完整描述BugA的生命週期。

9. 會議的會後總結

凡是進行會議,無論是電話會議還是現場會議,在大家討論過後,需要有會議記錄員記錄在會議上的決定,記錄哪些問題是在會議上確定的,哪些是待定的,哪些是新增的,這些由會議記錄員來記錄,並將上述事項發給參會人員以及那些無法參會但有重要關聯的人員,同時@相關人員,將會議上已確定的事項進行分派,便於問題推動以及跟進。

10. 溝通轉述問題

在答覆測試的疑問,有些點需要向其他人員進一步詢問再答覆給測試。在得到其他人員的回覆後,在轉述會給測試時,不要簡簡單單的截一個與其他人員的溝通截圖,讓測試自己去揣摩結果,也不要將其他無關的溝通細節回覆給測試,應當提煉與此問題緊密相關的結論,並以簡潔精煉的方式來回復。

在給別人傳輸文件時,除了文件名稱要見名知意外,還要附加一句簡短的文件說明。

在傳給別人圖片時,較好的操作是在圖片中新增說明,以畫框、高亮、簡潔文字說明等方式都。

為了防止溝通中的理解偏差,可以將別人給的答覆,用自己的話轉述一片,讓別人再次確認,類似於TCP的三次握手中的第三次確認過程,達到對該問題的一致理解。

作者:浩天之家 出處: http://www.cnblogs.com/cherishui/ 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利. Top 收藏 關注 評論