システムハンガリー記法はまだ有用な慣習ですか?[閉まっている]


23

私はフォーラムを検索しましたが、なぜ回避すべきかという答えは見つかりませんでした。なぜそれが特効薬ではないのかだけです。ですから、この質問は重複しているとは思いません。

そこにあるVALIDに慣れて、私はシステムハンガリーIを捨て去る必要がある理由は?

これまでのところ、私はそれを使用することで以下の利点を見ています:

  • 一貫した変数の命名
  • 検索せずにタイプが表示されます(インテリセンスは半分の時間でデッド/インデックス付けされているため、依然として正当な理由です)
  • セマンティクスは名前の2番目の部分に引き続きパックできます

そして、次のマイナス面:

  • 一部の人々を困らせます(理由はわかりません)
  • 型が変更された場合、その型は変数の名前と一致しない可能性があります(正当な理由ではないと思います。型はめったに変更されず、「すべての名前を変更」します)

なぜ:

vector<string> vecCityNames;
wstring strCity = L"abc";
//more code here
vecCityNames.push_back(strCity);

より悪い:

vector<string> cityNames;
wstring city = L"abc";
//more code here
cityNames.push_back(city);//Are we pushing back int on a queue? Float on a stack? Something else?

4
インテリセンスが死んでいる場合、コードは無効です。無効な場合、なぜ変数名が正しいと仮定しますか?
バブルラップ

6
@Bubblewrap:ほとんどのインテリセンス実装は、有効なコードであっても3秒間たまに動かなくなります。また、コードがコンパイルおよびリンクされていても、まったく機能しない場合があります。適切な規模のプロジェクトについて話している。
コーダー

9
ならないvectCityNamesことがvectStringCityNames、あなたの一貫性のある引数のために多く、この「質問」は、より暴言の何よりも、あなたはあなたの心がアップしてきたが、これは閉鎖されるべきです。

8
「有効な」理由は何だと思いますか?
アダムリア

15
あなたの2番目の例は、あなたのコメントが示すように混乱させるとは思わない。の意味cityNames.push_back(city)はかなり明確です。これは都市名のリストであり、追加しています。
クリスバートブラウン

回答:


62

私は(数年前)それを使用していましたが、もう使用していません。主な理由は、私がたまたま自分のキャリアのほとんどを使っていた強力な型付け(C ++、Java)を持つオブジェクト指向言語では不要だからです。これらの言語では、型を適切に定義すると、コンパイラーが型の安全性を強制できます。そのため、名前付けプレフィックスはすべて混乱しているため、名前が長くなり、読み取りや検索が難しくなります。

よく書かれたオブジェクト指向プログラムでは、ほとんどの変数はユーザー定義型(への参照)です。これらに同じ一般タグ(o「オブジェクト」など)をプレフィックスとして付けた場合、その利点は得られず、欠点のみが得られます。ただし、タイプ固有のタグを接頭辞に付けると、よく似た名前*を持つ1000種類の異なる略語を見つけようとする迷路に入り、タイプまたはその名前が変更されたときにそれらをすべて変更することを忘れないでください(これはよく管理されたプログラムではまったく珍しいことではありません)。

もちろん、これは非OO言語には適用されず、弱くおよび/または動的に型付けされた言語には適用されない可能性があります(C以外はこれらの経験はありません)。使用可能なIntelliSense(またはそのローカルの同等物)のない準最適なエディター/ IDEにも。そして、これはちょうど私の2セントです。したがって、ハンガリーの表記法があなたのチームとプロジェクトのために機能するなら、それを選んでください。重要なことは、プロジェクトを開始するにこれに同意すること(および一般的な一貫したコーディングスタイル)同意し、常に一貫性を保つことです。

* 私たちの現在のプロジェクトからわずか短いリスト:我々は持っているChargeChargeBreakdownChargeCalculatorChargeDAOChargeDTOChargeLineHelperChargeMapsChargePairおよびChargeType、他の中。さらにContract、s、Countries、Checkouts、Checkins ...もあります。これは、おそらくOPによって「合理的なサイズ」と呼ばれることもないプロジェクトの文字Cです。


免責事項:私は実際にハンガリー人なので、この問題については当局と話すことができると信じています;-)


「強力な型付け」-C ++に真に強力な型システムがあれば、変数名に型をハックとして埋め込む必要はありません。
マイケルバージ

19
@MichaelBurge:それがポイントです。する必要はありません。そうだから。
DeadMG

8
ユーザー定義型に関するポイントについては+1。iPosまたはという名前の変数を使用fAmountすることはできますが、すべてのオブジェクト変数に「構造体へのポインタ」であることだけを知らせる冗長な6文字のプレフィックスが与えられているコードベースで作業してみてください。

2
GUIの例外は、値に加えて各コントロールのハンドルを保存する必要があるため、エントリボックスに別の名前を考える必要はなく、テキストとhTextを作成します。ハンドルが特別な型ではなく単なるintであるシステムでは特に重要です。
マーティンベケット

1
Javaがハンガリーの表記法の使用を推奨すべき主要な場所は、変異しているが共有char[]されてStringBuilderいないインスタンスへの参照(例えば、によって保持されている)と、変異していないインスタンスへの参照を区別することであると仮定しますが、それらを変化させないものと共有することができます(複数のインスタンス間で共有される可能性のあるchar[]によって保持されるStringなどString)。両方のフィールドは同じタイプchar[]ですが、非常に異なるものを保持しています。可変性関連のバグの多くは、...から幹
supercat

35

どうしてstd::vector<string> vecCityNames;悪いの?

通常使用されるハンガリー語表記の問題は、プロファイリングで都市名をむしろ保持する必要があることが示されstd::dequeた場合、そのタイプのオブジェクトを参照するすべての変数名は突然誤解を招く名前を持つことになります。

次に、すべての変数の名前を変更しますか?大きなプロジェクトでそれを試みたことがありますか?マーフィーの助けがあれば(そしてその人は信じられないほど助けになります)、誰かが確かにのような変数を使用しdeqCityNamesているので、変更によってビルドが中断され、半年の間、だれも見てもいなかったコードを何時間もいじっていますで、毒獣に噛まれることを恐れて。

しかし、私が知っていることから、Charles Simonyiがハンガリー語を思いついた方法から、接頭辞は構文のタイプではなく、変数の意味の使用法を示していました。つまり、都市名のリストの適切なプレフィックスは、それがどのタイプで実装されているかに関係なく、おそらく(または、あなたにとって十分に暗号化されていない場合)です。listCityNameslstCityNameslist

しかし、複数形(「名前」)がそれが都市の集まりであることを既に伝えているので、私はその接頭辞はかなり不必要だと考えます。結論:慎重に識別子を選択する場合、ハンガリー語表記はほとんど必要ありません。OTOH、それが一般的に使用される方法は、長期的には、実際にコードにダメージを与えることです。


6
@Coder:このタイプはプロジェクト全体で使用され、このタイプのすべての変数にはプレフィックスが付きます。1つのグローバル変数ではなく、数百のローカル変数の名前を変更する必要があります。
sbi

7
Joel Spolskyのブログ投稿へのリンクを追加する必要があります。ここでは、変数タイプを使用してハンガリー語の通知を作成することが、それが何であるかについての誤解である理由について説明しています。あなたのものは良いですが、一部の人々はより権威のあるものを探しているかもしれません。joelonsoftware.com/articles/Wrong.html
シェーンWealti

2
@Coder:残念ながら、typedef非常に過小評価されているツールです
sbi

4
@シェーン:私はこの問題について自分の意見を書き留めました。それがJoelのものに合うようになったら、それで私は大丈夫です、なぜなら私は彼らのいくつかに同意しなくても彼の意見を評価するからです。しかし、10年以上の苦労の経験に基づいている場合、自分の意見を支持するために他の「当局」に訴える必要はないと思う。そのリンクを投稿してくれてうれしいですが、比較する他の人の意見を見るのはいつでもいいことです。
sbi

4
昔、私はこのショップのCVS担当者でした。トップデベロッパーの1人がイニシャルを変更しました(性転換手術など、彼と彼女のファーストネームは同じイニシャルを持っていませんでした)。彼女がファイル(または同様のファイル)に触れるたびに、彼女は彼のすべてのイニシャルを新しい形式に変更しました。歴史的特徴にさまざまな小さな変更があるため、これは非常に迷惑であり、実際に変更されたものとその理由を理解することは困難でした。変更vecCityNamesdeqCityNames数百のファイルで、あなたは同じことを行います。
デビッドソーンリー

15

なんらかの理由で、ここでの既存の答えは、ハンガリーの表記法の理論的根拠に沿って踊っているようです。ハンガリー語の表記法は、言語自体でそうすることが困難な場合に、(型理論的な意味で)型情報を追加するのに役立ちます。たまたま、C ++またはJavaの型システムをハンガリー表記(通常は説明)が完全に不要になるように使用することはそれほど難しくありません。これがおそらく反発の原因となります-プログラマーの作業が追加されますこれらの注釈をすべての変数naesで維持しますが、追加の値はほとんどまたはまったく提供しません(コードが乱雑に見えるため、害を引き起こす可能性もあります)。

一方、一つの(に、再び情報を入力するハンガリー語表記の使用を制限する場合はタイプ理論的)であることはありません言語によって自然にカプセル化されている場合、非常に便利です。たとえば、CとC ++は配列参照をポインター型として渡しますが、配列参照とポインターには異なる操作があり、それらに対して実行する必要があります。最初の要素を超えて配列にインデックスを付けることができます。これは、配列が引数として関数に渡されるとすぐに型システムに失われる有用な情報です。そのため、私たちのグループでは、CおよびC ++コードの変数名注釈を採用して、ポインター変数が実際に単一の要素へのポインターであるか、配列へのポインターであるかを区別しています。この規則を採用することは、コードベースでのメモリ破損の問題の発生を大幅に削減することに部分的に関与しています。


ハンガリー語を失敗させたのは、その意味的な意味ではなく、変数の構文タイプをエンコードするために(WinAPIチームによって)誤用されていたことです。(考えてdw対をcb。)それは、元のフォームはオブジェクト指向言語ではあまり有用であろうということではありません:インデックスはクラス型に保存されているのではなく、内蔵しても、まだインデックスです。
sbi

1
ここでの真の議論は型理論に関するものであると指摘して+1。ハンガリー語表記は、追加情報で型システムを拡張するための手法であり、その美的メリットについて議論するのではなく、型システムを拡張するための他の手法(テンプレート、typedefなど)と比較および対比する必要があります(またはその欠如)。
ダニエル・プライデン

1
質問は、具体的には「Systems Hungarian」、宣言された型の無意味な複製に関するもので、追加のセマンティック情報はありません。セマンティックタグの元の「ハンガリー語表記」の概念を使用して、言語構文(Cなどの一部の言語ではC ++ではなく、ユーザー定義型でより確実に行うことができる一部の言語)で許可される情報を超える場合があります)、しかし、それは質問の目的ではありません。
マイクシーモア

10

一部の人々を困らせます(理由はわかりません)

それが私を悩ます理由は、コードの視覚的なスキャンが遅くなるのは、すべての単一の識別子の小さな速度のバンプだからです。それはmAs bIf pYou kHad zTo qiEnglish cText lLike uThisを読む


9

憎しみは言葉が強すぎる、IMO コードは自由に作成できます。私は自分のコードでハンガリー語の表記法を使用しないことを好み、他の人のコードでそれを読んだり作業したりする必要がないことを選択します。

何人かの人々がハンガリーの記法を煩わしいと思う理由を尋ねました。私は他の人のために話すことはできませんが、それが私を悩ます理由は次のとおりです。

  1. それは醜いです。ハンガリー語は完全に合理的な名前を取り、コードに相当するものを追加します。このコードを内部化したら、完全に理にかなっていると確信していますが、初心者にとっては、誰かが私のソースコードでC ++の名前マングラーを解き放ったように見えます。

  2. 冗長です。変数の宣言はその型を確立します。変数名にその情報を繰り返す必要はありません。これはすべての言語に当てはまるわけではありません。たとえば、Perlでは、変数名の前に@$などのシギルが本質的に変数の型を定義するため、使用する以外の選択肢はありません。

  3. それは私が持っていない問題を解決します。メソッドと関数は、ローカル変数またはパラメーターの宣言を見つけるのに苦労する必要があるほど長くすべきではありません。また、何が何であるかを追跡するのに苦労するほど多くの変数を含むべきではありません。この点でも、ローカル変数を使用するコードの近くでローカル変数を宣言すると役立ちます。過去のCコンパイラでは、すべてのローカル変数を関数の先頭で宣言する必要がありましたが、その制限はかなり前に削除されました。

  4. 不完全です。ハンガリー語表記は、型システムを持たない言語(BCPL)のために考案され、後にかなり限られた数のネイティブ型を持つ言語(C)で広く使用されました。IMO、C ++やJavaなどの広範な型システムを持つ言語ではうまく機能しません。なぜ接頭部を使用して、char []のようなネイティブ型であるが、クラスではない変数の型を示す必要があるのですか?あるいは、vecクラスのようなプレフィックスの作成を開始すると、クラス階層に平行したプレフィックスの大きな階層ができあがります。それがあなたにアピールするなら、あなたはそれに歓迎します。それについて考えるだけで頭痛がします。

  5. 少なくとも私が理解している限り、それはあいまいです。違いは何だszFooとはpszFoo?最初はゼロで終了する文字列で、2番目はゼロで終了する文字列へのポインタです。しかし、CまたはC ++では、私が知る限り、文字列変数は事実上ポインターであるため、同じであるかどうかはわかりません。どちらを使うべきですか?実際の答えは本当に重要ではありません-ポイントは、私がこれらの種類の質問を避けるのに役立つはずのまさに表記法を使用して答えを見分けることができないということです。一方、変数の宣言はコンパイラが使用するものであるため、明確でなければなりません。

これらは、ハンガリー記法についてを悩ますものです。しかし、グループとしても、ハンガリー人がほとんど放棄された理由を彼らが完全に説明しているとは思わない。ほとんどのプログラマーがハンガリー語を使用しない最大の理由は次の3つです。

  1. それを使用する説得力のある理由はありません。上記の項目3および4を参照してください。ハンガリー語がハンガリー語を使用しないことに対して大きな利点を提供した場合、私はおそらく迷惑に耐えることができますが、私はそれを見ません、そして明らかに他のほとんどの人々もそうではありません。おそらくハンガリー語で一番いいのは、それが広く使われている慣習であり、標準の使用にこだわるなら、同様のスキルを持つ他のプログラマーが表記法を理解できると合理的に期待できることです。

  2. マイクロソフトではない企業の影響力の増加。ハンガリー語の表記法を採用したほとんどのプログラマーは、Microsoftがコードを記述した方法であり、多くの場合、流れに沿って移動する方が簡単だからだと言ってもいいでしょう。グーグルやアップルのような企業は、過去よりもはるかに大きな影響力を持っています。そして、これまでよりも多くのプログラマーがハンガリーやその他のほとんどの企業のスタイルを採用しています。(まだいくつかのレムナントが表示されていることを指摘するのは公正です。たとえば、GoogleとAppleの両方が定数名に「k」プレフィックスを使用することがよくあります。)

  3. マイクロソフト自体がハンガリー語を放棄しました。コーディングガイドラインのMicrosoftのGeneral Naming Conventionsセクションを確認すると、「ハンガリー語表記を使用しないでください」と太字で示されていることがわかります

したがって、ハンガリー語表記の使用を停止する正当な理由の1つは次のとおりです。

ハンガリーの表記法の人気は、条約がもはや役に立たなくなるまで減少しました。最近ではハンガリー語を使用したり理解したりするプログラマーが非常に少なくなり、したがって、この規約は想定される情報を伝えるのにはるかに効果的ではありません。自分の個人プロジェクトでコードを書くのに便利な方法だと思うなら、やめる理由はほとんどありません。ただし、ハンガリー語を使用しないチームの一部としてコードを作成している場合、コミュニケーション戦略が成功する代わりに、あなたと他のチームとの間の壁になる可能性があります。


「の違いは何だszFooとはpszFoo」?1つはchar*、もう1つは、char**差を伝えるのに0.25秒かかりました。Intellisenseでそれを打ち負かしてみてください。
コーダー

2
@Coder pnFooはおそらくint*でなくint**であるためsz、ポインタも意味することを知っておく必要があります。ハンガリー語の接頭辞を確立した限られた数の型にとっては大きな問題ではないと確信していますが、大規模なプロジェクトで定義された数千の型の数です。Intellisenseについては知りませんが、IDEは過去25年間で着実に改善されており、この傾向は今後も続くと予想しています。
カレブ

8

これまでのところ、私はそれを使用することで以下の利点を見ています:

  • 一貫した変数の命名

すべての変数にThe Simpsonsの文字にちなんで名前を付けると、一貫性がありますが、利点はありますか?

  • 検索せずにタイプが表示されます(インテリセンスは半分の時間でデッド/インデックス付けされているため、依然として正当な理由です)

これは、特定のツールの弱点に基づく唯一の正当な理由です...

  • セマンティクスは名前の2番目の部分に引き続きパックできます

それは利点ではありません。単に(大規模な)マイナス面がないと主張しているだけです。


6

IDEは、マウスオーバーしたときに変数のタイプを簡単に教えてくれます。では、なぜその情報を複製するのが面倒なのでしょうか?基本的に、Systems Hungarian NotationはDRYの違反であり、それに関連するすべての落とし穴があります。現代の環境でその情報に簡単にアクセスできる場合、その代価を支払う理由はありません。

一貫性自体は利点ではありません。タイプに名前を付けないこと一貫しています。一部の変数の名前にタイプが含まれている場合にのみ、矛盾が発生します。そして、セマンティクスを2番目の部分にパックすることは、単に「まあ、それほど悪くない」ということです。他の誰もがセマンティクスに名前全体を使用するようになります。記載されている本当の利点はありません。


4
「IDEは、マウスオーバーしたときに変数の型が何であるかを簡単に教えてくれます。」、こんにちは、はい。大規模なプロジェクトでは、この機能は非常に信頼性が低く/遅いと感じています。ctrl + space、ctrl + space、ctrl + space、ctrl + space、ctrl + space、no go
...-コーダー

3
新しいIDEを入手してください。または、驚異的に機能するSSD。または、不要なヘッダーを少なくするだけです。
DeadMG

1
変数の型を表示するときにIDEが遅すぎる場合、または単にそれを行うことができない場合でも、変数の宣言がその使用から遠く離れないように、メソッド/関数を短くする必要があります。
ケビンパンコ

6

ハンガリー表記の伝統的な形式のもう1つのポイントは、通常は接頭辞です。ここには2つの問題があります:

1)人間の読者は一般に最も重要な情報を最初に好むでしょう。ハンガリー語のほとんどの形式では、エンコードされた情報は名前よりも重要性が低いと考えられます。

2)接頭辞は字句ソートに影響するため、たとえば、接頭辞を使用してインターフェースまたはクラスを示し、IDEがこれらのソート済みリストを提供する場合、関連するクラス/インターフェースはこのリストで分離されます。


2

明らかに、これは意見に帰着するので、ここで事実を扱うのは難しいでしょう。個人的には、ハンガリー語表記法の議論、強く型付けされたオブジェクト指向言語ではやや薄いことがわかります。私の経験では、OOアプリケーションはクラスの一貫性と簡潔さを保つことで複雑さを処理する傾向があり、関数についても同じことが言えます。これは、他のすべてのものが同等であることを意味します:

  • より多くのクラス/タイプ
  • より短い方法

ハンガリー語表記を使用する場合は、全体に適用するか、特定の特権タイプとクラス(コアライブラリクラスなど)に使用するかを決定する必要があります。後者は私には意味がなく、前者はペテル・トレックが言及していた「千種類の異なる略語を見つけようとする迷路」につながります。これは、略語リストの維持にかなりのオーバーヘッドがあることを意味し、通常、「一貫性のある変数の命名」はウィンドウの外に出ます。

短いメソッドに関する2番目のポイントは、ほとんどの場合、変数のタイプをチェックするために数百行のコードを調べる必要がないことを意味します。変数にもう少し慎重に名前を付けると、他のいくつかの質問(例cityName:ちょうど)が排除されますcity。私はそれcityNameがフロートではないことを願っています:)

なぜ人々を困らせるのか-繰り返しますが、これはおそらく慣れるかどうかにかかっています。しかし、慣れていない人として、ハンガリー語の表記法を使用すると、私の目でのコードの流れが崩れ、すぐに読むのが難しくなることがわかります。要約すると、リファクタリングなどの点でいくつかの欠点については説明していませんがメリットがないと言っているのではありません


1

C ++のコンテキストではわかりませんが、Java / C#の世界では、文字列であると言うよりも、ドメイン言語またはコンテキストのいずれかを伝える意味のある名前を使用することを好みstrFirstNameます。それが文字列であること、またはより良い意図を伝えるために名前をリファクタリングする必要があることは明らかです。作業対象のタイプを知るために接頭辞が必要な場合は、名前が一貫していないか、説明が不十分であるか、まったく間違っていると主張します。現代の言語では、あいまいな名前や曖昧な名前よりも、あいまいさのない長い名前を常に好みます。

私はハンガリーを使用する唯一の時間はASP.NETコントロールのためであり、IAは)本当に長いようなものを入力する必要はありませんので、それはより多くのだCustomerFirstNameTextBox対をtxtCustomerFirstName、そしてB)だから、インテリセンスは、コントロールの種類のすべてをソートします。しかし、それをしても「汚い」と感じますが、まだもっと良い方法を見つけていません。


0

Meh-どれほど厳しく選択を合理化しようとしても、それは本当に個人的な好みです。個人的には「When in Rome ...」ルールに固執し、Windows APIを頻繁に呼び出すコードでハンガリー語を使用しています。プラットフォームに依存しないコードについては、C ++標準ライブラリスタイルに従う傾向があります。


0

答えはこの質問にあります。次の変数に名前を付ける方法を教えてください。

char * nullTerminatedString;
wchar * nullTerminatedWideString;
string stlString;
wstring stlWideString;
CString mfcString;
BSTR comString;
_bstr_t atlString;

これらの定数文字列、これらへのポインター、およびこれらへの定数ポインターに追加します。


3
szFoowczFoostrFoo(w)strFoostrFoobstrFoobstrFoo
コーダ

0

あなたが説明するハンガリー記法の形式は強く嫌いです。理由?90%の時間を無駄にすることはありません。

たとえば、私が我慢せざるを得ないレガシープロジェクトからのコード(同等のC ++。実際にはDelphiで記述された)コード:

pRecords[0]->FooMember=10;

... pRecordは変数であり、TRecordList型です。 TRecordList *pRecords[10];

これは、「フィールド」か「メンバー」かによって、fFooMember ...またはmFooMemberを指すFooMemberという名前のオリオーティで構成されるクラスです(ヒント:それらは同じものです)

問題?fFooMemberFooMember_のようなものになります。これは、常にFooMemberパブリックプロパティを介してアクセスするためです。pRecords?それはあちこちでそれを間接参照しているという事実からのポインタだということは明らかです。TRecordList?型名とその型のオブジェクトを混同する可能性があるのはいつですか?コンパイラはあなたに怒鳴り、型はオブジェクトが存在する場所ではほとんど使用されません(静的プロパティ/メソッドを除く)

さて、ハンガリー記法を使用する場所が1つあります。これは、他のUI変数または通常の変数と同じ名前を持つ多くのUI変数を扱う場合です。

たとえば、あなたの名のフォームがありました。

FirstNameFormというクラスがあります。その中で、それぞれラベルとテキストボックスのlblFirstNameとtxtFirstName。テキストボックスで名前を取得および設定するためのFirstNameパブリックプロパティ。

これはFirstNameLabelとFirstNameTextBoxを使用して解決することもできますが、入力するのに時間がかかります。特にGenderDropDownListなどのようなもの。

したがって、基本的には、ハンガリー語の表記法は、せいぜい体系的なレベルで迷惑であり、最悪の場合は有害です(他の答えはリファクタリングと一貫性の問題について示しています)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.