The Hungarian Notation
Posted on January 22nd, 2006 at 3:46 by fr3@K

在 open source 的世界也好, 在公司內部也好, 任何像樣的 project, 大都免不了採用或自訂一套 coding convention. 不同 coding convention 所要達成的目標並不盡相同, 但都有個共同點 - 讓你寫的 code 看起來像是別人寫的. 主要原因是 - 這樣做應該可以讓他人容易閱讀/理解/修改你寫的 code.

Coding convention 主要分為兩個部份:

  • Naming notation (命名法)
  • Formatting (程式格式/排版)

以我個人經驗以及從朋友處得到的消息來看, 公司內部最常採用的 naming notation 是 Hungarian Notation (匈牙利命名法). 把 Hungarian notation 傳播到世界各地, 甚至錯誤地使用在例如 C++ 之類的 strong-typed (或是接近 strong-typed) 語言上, M$ 功不可沒, Win32 SDK 與 MFC 是其中經典之作. 時至今日, 就連 M$ 內部也已展開了反撲, 最好的例子就是 .NET 丟開 M$ 過去採用 hungarian notation 的包袱.

痛恨 hungarian notation, 但這通常不會造成我在工作上的困擾. 我總是能幸運地說服同事與上司放棄它, 或至少不強迫我採用它. 不過還是常會有朋友跟我抱怨公司強迫他們採用 hungarian notation, 他們多是無奈接受. 這帖 blog, 就是為了這些朋友寫的, 如果你剛好在這些公司工作, 不妨把這帖 blog 的 link 轉給你的同事或上司.

Annoyances of the Hungarian Notation:

  • 視你為弱智. 認為你替變數取的名字大都不好, 很難從名字辨認大約的型別
  • 視你為白痴. 認為你有可能會 - 把一個叫做 size 的變數 (不是 integral type 還能是什麼?) 誤判為一個 ifstream 的 instance
  • 視 strong-typed compiler (如 C++ 編譯器) 為低能. 認為 compiler 有可能會 - 在你把一個叫 name 的變數 (不是某種字串還能是什麼?) 當作 ComboBox 來操作時, 不產生 compile error

我常用的命名法則是盡量口語化, 並試著恰如其分地命名. 舉例說明較快:

  • Instance of integral type
    • unsigned long user_count;
      int offset;
      size_t index, received_bytes;
  • User-defined type
    • class Contact;
      class FastString;
      typedef list<Contact> Contacts; // or ContactList
  • Instance of user-defined type
    • string english_name;
      Contacts kens_contacts; // or contacts_of_ken
      Window main_window;

誤判以上所舉例子型別的人, 或許該考慮換個工作 :(.

當然, 上例都是淺顯的例子, 從我個人經驗來說, 應用這原則倒也沒遇過特別困難的狀況. 我想說的並不是我用的方法多好, 而是希望別再有更多人強迫他人或被他人強迫用什麼彆腳的 dwData, wndMain, ctrlBrowser, nCount, szName 來寫 C++.

del.icio.us:The Hungarian Notation digg:The Hungarian Notation spurl:The Hungarian Notation newsvine:The Hungarian Notation furl:The Hungarian Notation Y!:The Hungarian Notation 黑米共享書籤:The Hungarian Notation 推推王:The Hungarian Notation
Previous Post
« C++ Terminology - 0. 前序 «
Next Post
» C++ Terminology - 1. Variety of Types »

2 Comments »

Comment #39

size 可以是float, double, DWORD, WORD, size_t
某些時候我希望是 D3DVECTOR3 ….(3度空間下)

所以我不認為Hungarian Notation就是很笨的方法.
雖然我也不是完全遵守…

Comment by 也用C++的程式設計師 — July 12, 2006 @ 15:36


Comment #40

我能想像到型別為 float, double 等的 variable/argument 都跟 size 無關呢. 我想到的是 ratio, rate 等等. 不過這也有可能是因為我工作的項目都與浮點數無關 (或許跟我缺乏想像力比較有關系), 導致我想像不到.

DWORD, WORD, size_t and etc. 不都是整數 (integral) 型別嗎? 你大概沒注意看吧 :P

或許是我表達得不夠好, 我想說的重點並不在於在不用 hungarian notation 的情況下, 能不能由 variable/argument name 精準判別出型別. 而是好的 variable/argment naming 是必要的 (與 variable/argument 型別無關). 而這會導致一個好的副作用, 就是由 variable/argument name 即可看出 variable/argument 的大約型別.

而在我個人的經驗, 這已經足以應付絕大部分情況. 又, 運用 hungarian notation 該如何準確命名一個 tree view control (假設這個 control 的型別名稱為 CTreeView)? 或許可叫 tvCtrl, ctrlTreeView 等等. 可是這樣的 variable/argument name 雖然或多或少能一目了然它的型別, 卻是一個非常不好的命名, 因為這只能讓人知道型別卻不了解用途. 命名為 folderView (假設用途是顯示某個目錄以下的結構) 或是 familyTree (假設用途是顯示某人的族譜) 等等, 既能清楚表達用途, 也多少能讓人看出大致型別, 這不是更好嗎?

Comment by fr3@K — July 12, 2006 @ 18:01


Comments RSS TrackBack URI

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>