2010-02-12 83 views
1

我將在此處對我對When a method has too many parameters?發表的評論展開討論,其中OP對於具有97個參數的其他人的功能存在小問題。如何提高功能的可維護性

我非常信任編寫可維護的代碼(而且它通常比編寫代碼更容易,因此Steve McConnell(稱讚他的名字)的短語「只寫代碼」)。

由於統計了大多數車禍發生在路口的情況,而且我的經驗(ymmv)顯示界面上出現大多數「異常」,所以我會列出一些我爲避免界面誤解而做的事情,並邀請您的評論我錯了。

但是,更重要的是,我邀請您的建議,使事情更具預防性(請參閱,畢竟有一個問題 - 如何改進的東西?)。

  • 適當的文檔,以(最新)DoxyGen格式註釋的形式描述每個參數的性質和海豚。
  • 絕對帶有全局變量作爲隱藏參數的後門詭計。
  • 嘗試將參數限制爲六個或八個。如果更多,則將相關參數作爲結構傳遞;如果他們不相關,那麼認真重新考慮功能。如果需要這麼多的信息,維護起來太複雜了嗎?它可以分解成幾個更小的功能嗎?
  • 儘可能地使用CONST並且有意義。
  • 一個編碼標準,它表示輸入參數先來,然後是輸出,最後是輸入/輸出,這些都是由函數修改的。
  • 我也#定義一些空宏作出聲明更容易閱讀:

    #定義輸入
    #定義輸出
    #定義MODIFY
    布爾DoSomething的(INPUT INT howOften,MODIFY Wdiget *進myWidget, OUTPUT WidgetPtr * const nextWidget)

只是一些想法。我如何改進這些?謝謝。

+1

將參數限制爲六個或八個?爲什麼不是七?什麼時候最多可以是一個或另一個? – waiwai933 2010-02-12 05:41:30

+2

標題是怎麼回事? – womp 2010-02-12 05:44:46

+1

您的DoSomething功能的參數無序。 :-) – xpda 2010-02-12 17:23:05

回答

4

解決您的積分依次是:

  1. 精心設計的類型通常呈現的Doxygen格式的註釋是浪費時間。
  2. 儘管如上所述(「shenanigans」根據定義是錯誤的),但並非所有使用全局圖的人都像許多人所暗示的那樣糟糕。如果在真正使用之前必須傳遞一個參數超過四次,那麼全球可能不太容易出錯。
  3. 八個甚至六個參數通常過多。任何超過兩個或三個開始表明該函數正在做的不止一件事。一個明顯的例外是將許多其他項目彙總到對象中的構造函數(例如,將街道名稱,號碼,城市,國家,郵政編碼等作爲輸入的地址對象)。
  4. 更好地聲明爲「寫入常量正確的代碼」。
  5. 鑑於C++的默認參數能力,通常最好按照可能性從小到大的順序進行排序,以使用默認值。
  6. 不要。不要!如果不明確什麼是投入和產出是什麼,那就證明基本設計是致命的缺陷。

至於想法,我覺得其實是不錯的:

  1. 正如第一點暗示,專心類型。一旦你把它們弄對了,其他大部分問題都會消失。
  2. 使用一些(甚至只有一個)中心主題。對於Lisp,一切都是列表。對於Unix,一切都是文件(文件都是簡單的字節流)。模仿這種簡單性。

編輯:回覆意見:

  1. 雖然你有一個點的東西,我的經驗仍表示與Doxygen的(以及類似如的javadoc)產生的文檔幾乎普遍沒用。從理論上講,這個工具並不妨礙體面的文檔,但實際上它最好是罕見的。
  2. 全局變量肯定會造成問題 - 但我已經足夠大了,可以在提供多種選擇之前使用Fortran,並且在某種程度上它確實不像許多人暗示的那麼糟糕。很多故事似乎至少是第三手,每次重新講述時都會添加一些額外的「香料」。我看過一個故事,聽起來很像幾十年前我講過的一個誇張版本...
  3. 嗯...... Markdown格式似乎不贊成我的跳過數字。
  4. 再次...
  5. 我的評論是特定於C++,但其他一些語言也支持默認參數和/或重載,它也可以適用於大多數。即使沒有它,像f(param1, param2, 0,0,0);這樣的電話很容易被看作具有默認參數。在某種程度上,通過使用順序是很方便的,但是當你選擇的訂單與簡單一致無關。
  6. 確實,一個void *參數並沒有告訴你很多 - 但MODIFY void *好一點。 const的實際類型和一致用法提供了更多信息,並由編譯器進行檢查。其他語言可能沒有/使用const,但它們可能也沒有宏。 OTOH,一些直接支持你想要的 - 例如,Ada有in,outinout說明符。
+0

對類型的評論+1。儘管Lisp中的所有內容都不一定是一個列表,但這仍然是一個很好的觀點。 – asm 2010-02-12 17:31:11

+0

@Andrew:我的簡單化僅僅是同一個想法的另一個例子。這是我的故事,我堅持不懈! – 2010-02-12 17:40:01

+0

1「精心設計的類型通常會使Doxygen格式評論浪費時間」 - 也許如果您正在查看代碼。如果你在公司的itra-web上查看界面文檔(這很容易通過超鏈接導航),也許不會。 2 - globals不壞?嗯,好吧,製作這個「裸體」全局變量。如果沒有包含在內,全局變量就是一件壞事。 YMMNV。 3 - 是的,我傾向於在大約4處聞到不好的代碼。 5 - 優秀點! (儘管帖子是語言不可知的)如果我重新排序輸出,修改,輸入,這足夠了嗎? contd ... – Mawg 2010-02-14 02:38:30

2

我不確定我們是否會就此達成一致意見,每個人都會想出不同的想法(好壞在彼此的視角)。話雖如此,我發現Code Complete是一個很好的去處,當我遇到這樣的問題。

+0

+1代碼完成(雖然我不知道它在什麼地方解決這個問題) – Mawg 2010-02-14 02:40:47

0

我會使用鮑勃叔叔在他的書「清潔代碼」中提出的'規則'。

這些那些我想我還記得:

  • 2參數正常,3是壞的,更需要重構
  • 評論都是不好的名字的標誌。所以應該沒有,功能的目的和參數應該清晰地從名稱
  • 使該方法簡短。瞄準10行以下的代碼。
+1

一個函數名可能是清楚的給你,但不是一些隨機開發誰會在幾年後讀你的代碼。我認爲總是需要意見來讓事情變得非常清楚! – 2010-02-12 13:39:00

+1

我是鮑勃,我是叔叔,我支持評論。即使使用了很好的代碼,正確使用註釋也會使不重要的軟​​件更快理解。 – xpda 2010-02-12 17:26:39

+0

他對評論的評論是基於糟糕的評論 - 試圖回答「什麼」問題的評論。有用的評論大多回答「爲什麼」的問題。例如:「這使用插入排序而不是快速排序,因爲數據始終以至少95%的排序開始。」它們在這樣的情況下特別有用,在那種情況下做出了不尋常的選擇,後來的讀者可能會認爲它是在無知的情況下完成的,否則會浪費時間在錯誤指導的變化上。 – 2010-02-12 17:35:34

1

我的一個大問題是控制功能之間的耦合。 (控制耦合是當一個模塊控制的另一執行流程,通過傳遞標誌告訴調用函數做什麼。)

例如(削減從代碼&貼我剛上工作):

void UartEnable(bool enable, int baud); 

,而不是:

void UartEnable(int baud); 
void UartDisable(void); 

換句話說 - 參數傳遞 「數據」,而不是 「控制」。