web-dev-qa-db-ja.com

これはシンボリック定数オーバーキルの使用ですか?

私はソフトウェアエンジニアリングにかなり慣れていないので、学習課題としてチェスゲームを書きました。私の友人はそれを見て、私のコードは次のようになっていると指摘しました

for (int i = 0; i < 8; i++){
    for (int j = 0; j < 8; j++){

彼は代わりにそれがあるべきだと主張したが

for (int i = 0; i < CHESS_CONST; i++){
    for (int j = 0; j < CHESS_CONST; j++){

今は考えられないほど良いシンボル名が付いています。

もちろん、私は通常、マジックナンバーの使用を避けることを知っていますが、

  1. この数が変わることはありません。
  2. 番号はコード全体で非常に多くの場所で使用されているので、名前はとにかく説明的なものにはなりません。そして
  3. チェスプログラムのソースコードを使用している人は、チェスについて8の目的を十分に理解している必要があります。

シンボリック定数は本当に必要ありません。

それで皆さんはどう思いますか?これはやり過ぎですか、それとも慣習に従ってシンボルを使用するだけですか?

34
chocolatedevil

象徴的な名前を使用するのはあなたの友人の私見ですが、名前は間違いなく説明的である必要があります(BOARD_WIDTHではなくCHESS_CONSTなど)。

プログラムの存続期間を通じて数値が決して変わらない場合でも、プログラム内には、数値8が異なる意味で発生する場所が他にある可能性があります。ボード幅が意味するところはどこでも「8」をBOARD_WIDTHに置き換え、別のことを意味するときに別のシンボル名を使用すると、これらの異なる意味が明確になり、プログラム全体がより読みやすく、保守しやすくなります。また、ボード幅に依存するコード内のすべての場所をすばやく特定する必要がある場合に備えて、プログラム全体のグローバル検索(または環境によっては逆シンボル検索)を実行することもできます。

数値の名前を選択する方法(またはしない方法)については、この 以前のSE.SEの投稿 も参照してください。

ここでコメントで説明されているので、補足として:実際のプログラムのコードで、変数iがボードの行を参照し、jが列を参照するかどうかが重要である場合、またはその逆の場合、rowcolのように、区別を明確にする変数名を選択することをお勧めします。そのような名前の利点は、それらが間違ったコードを間違って見えるようにすることです

101
Doc Brown

わかりました、ここに私が持っているいくつかのコメントがあります:

マジックナンバーを取り除くことは素晴らしいアイデアです。 DRYと呼ばれる概念がよくありますが、それは誤って伝えられることがよくありますが、その概念は、プロジェクトの概念の知識を複製しないことです。したがって、ChessBoardというクラスがある場合は、それに接続されたBOARD_SIZEまたはChessBoard.SIZEという定数を保持できます。このように、この情報の唯一の情報源があります。また、これにより、後で読みやすくなります。

for (int i = 0; i < ChessBoard.SIZE; i++){
  for (int j = 0; j < ChessBoard.SIZE; j++){

数が変わらない場合でも、プログラムは間違いなく優れています。それを読んだ人なら誰でも、コードが何をしているかについての詳細を知っています。

悪い名前は、名前がないより悪いですが、それは何かに名前を付けるべきではないという意味ではありません。名前を変更するだけです。赤ちゃんをお風呂の水で捨てないでください。 :p名前は、それが何を説明しているかをよく理解している限り、わかりやすい名前にすることができます。次に、その概念を複数の異なるものに使用できます。

11
unflores