17

私が現在取り組んでいるコード ベースには、ハードコードされた値が散らばっています。

私はすべてのハードコードされた値をコードのにおいと見なし、可能な限りそれらを排除しようとしています...しかし、確信が持てない場合がいくつかあります。

ベスト プラクティスとは何かを考えさせられる 2 つの例を次に示します。

1. MyTextBox.Text = someCondition ? "Yes" : "No"
2. double myPercentage = myValue / 100;

最初のケースでは、設定ファイルで MyHelper.Yes と MyHelper.No を実行できるようにするクラスを作成するのが最善の方法です (ただし、変更される可能性は低く、変更される可能性があるかどうかは誰にもわかりません)その使用法で大文字と小文字が区別されるケースはありません)。

2 番目のケースでは、100 で割ってパーセンテージを求めることは、数学の法則が変わらない限り変わることはありそうにありませんが、もっと良い方法があるのではないかと考えています。

この種のハードコーディングに対処する適切な方法を提案できる人はいますか? また、ハードコーディングが許容される場所を思いつく人はいますか?

4

21 に答える 21

20

また、ハードコーディングが許容される場所を思いつく人はいますか?

  • 小さなアプリ
  • 独身男性プロジェクト
  • 捨てる
  • 短命プロジェクト

要するに、他の人によって維持されないもの。

ああ、メンテナー コーダーであることが過去にどれだけ私を傷つけたかに気づきました :)

于 2008-12-31T00:30:13.560 に答える
16

本当の問題はハードコーディングではなく、繰り返しです。"The Pragmatic Programmer"にある優れたアドバイスに従うなら、単純に Don't Repeat Yourself (DRY) です。

DRY の原則に従って、いつでも何かをハードコーディングしても問題ありません。ただし、その特定の値を再度使用する場合は、この値が 1 回だけハードコーディングされるようにリファクタリングしてください。

于 2008-12-31T01:15:33.687 に答える
16

もちろん、ハードコーディングが許容される場合もあります。ドグマに従うことは、頭脳を使うことほど役立つことはめったにありません。

(この例として、goto 戦争に戻るのは興味深いかもしれません。goto は悪であると聖なるすべてのことを誓うプログラマーを何人知っていますか? では、なぜスティーブ・マコーネルは、慎重な議論に十数ページを割くのですか? Code Complete の件名?)

確かに、小さな使い捨てアプリケーションが製品コードに変化することが多いことを示す苦労して得た多くの経験がありますが、それは熱狂する理由にはなりません。アジャリストは、機能する可能性のある最も単純なことを行い、必要に応じてリファクタリングする必要があると言っています。

それは、「最も単純なこと」が読み取り可能なコードであってはならないということではありません。使い捨てのスパイクであっても、次のように書くことは完全に理にかなっているかもしれません。

const MAX_CACHE_RECORDS = 50
foo = GetNewCache(MAX_CACHE_RECORDS)

これは、3 回の反復で、誰かがキャッシュ レコードの数を構成可能にするよう要求し、最終的に定数をリファクタリングする可能性があるという事実に関係ありません。

覚えておいてください、もしあなたが極端なものに行くなら

const ONE_HUNDRED = 100
const ONE_HUNDRED_AND_ONE = 101

私たちは皆、デイリー WTF に来て、あなたを笑い飛ばします。:-)

考え!それで全部です。

于 2008-12-31T13:46:52.470 に答える
7

それは決して良いことではなく、あなたはそれを証明しただけです...

double myPercentage = myValue / 100;

これはパーセンテージではありません。あなたが書きたかったのは:

double myPercentage = (myValue / 100) * 100;

またはより正確には:

double myPercentage = (myValue / myMaxValue) * 100;

しかし、このハードコーディングされた 100 はあなたの心を混乱させます...だから、Colenが提案したgetPercentageメソッドに行きます:)

double getpercentage(double myValue, double maxValue)
{
   return (myValue / maxValue) * 100;
}

また、ctackeが示唆したように、最初のケースでは、これらのリテラルをローカライズする必要がある場合、苦痛の世界になります。いくつかの変数や関数を追加するのは決して面倒なことではありません

于 2008-12-31T01:01:22.997 に答える
6

ローカライズする必要がある場合、最初のケースはあなたを殺します。アプリ全体の静的または定数に移動すると、少なくともローカライズが少し簡単になります。

于 2008-12-31T00:28:44.030 に答える
6

ケース 1:いつ何かをハードコーディングする必要があるか: それが変更されると考える理由がない場合。とはいえ、インラインでハードコーディングすることは絶対にしないでください。時間をかけて、静的変数またはグローバル変数、または言語が提供するものを作成してください。問題のクラスでそれらを実行し、コードの 2 つのクラスまたは領域が同じ理由で同じ値を共有していることに気付いた場合 (つまり、単なる偶然ではないことを意味します)、それらを同じ場所に向けます。

ケース 2:ケース ケース 2 については、あなたは正しいです。「パーセンテージ」の法則は変わらないので (ここでは合理的です)、インラインでハードコーディングできます。

ケース 3: 3 番目のケースは、物事が変わる可能性があると考えているが、ResourceBundles や XML などをロードする手間をかけたくない/時間がない場合です。その場合は、できる限りの集中化メカニズムを使用します (嫌われている Singleton クラスは良いクラスです)。実際に問題に対処する必要が生じるまで、それを使用します。

ただし、3 番目のケースは注意が必要です。アプリケーションを実際に実行せずに国際化するのは非常に困難です。そのため、ハードコーディングして、i18n 担当者がノックしてくるときにコードが最悪でないことを願うだけです。テイスティングコード周り:)

編集:前の開発者がコード (PHP) の 100 以上の場所に MySql 接続文字列を配置したリファクタリング プロジェクトを終了したことを述べさせてください。大文字の場合もあれば、小文字の場合もあり、検索や置換が困難でした (ただし、Netbeans と PDT は大いに役立ちました)。彼/彼女がこれを行ったのには理由があります (POG と呼ばれるプロジェクトは基本的にこの愚かさを強制します) が、同じことを無数の場所で繰り返すことほど、良いコードとは思えないものは何もありません。

于 2008-12-31T00:37:14.387 に答える
4

2 番目の例のより良い方法は、インライン関数を定義することです。

double getpercentage(double myValue)
{
   return(myValue / 100);
}

...

double myPercentage = getpercentage(myValue);

そうすれば、何をしているのかがより明確になります。

于 2008-12-31T00:27:50.290 に答える
4

ハードコーディングされたリテラルは、単一のテスト クラス内でローカル定数が役立つほど値が再利用されない限り、テスト値の単体テストに表示する必要があります。

単体テストは、抽象化やリダイレクトのない期待値の記述です。テストを読んでいる自分を想像してみてください。情報が文字通り目の前にあることを望んでいます。

テスト値に定数を使用するのは、多くのテストで値が繰り返され (それ自体が少し疑わしい)、値が変更される可能性がある場合のみです。

比較するテスト ファイルの名前などには定数を使用します。

于 2009-01-13T02:49:22.943 に答える
3

「ハードコーディング」は心配するべきではありません。ポイントは、特別な値がコードまたは構成ファイルのどちらにあるかではなく、ポイントは次のとおりです。

  • 値が変わる可能性がある場合、それはどれくらいの作業量で、見つけるのはどれくらい難しいですか? それをある場所に置いて、その場所を別の場所で参照するのはたいした手間ではないので、安全にプレイする方法です。
  • 保守プログラマーは、値が何であるかを確実に理解できますか? 少しでも疑問がある場合は、意味を説明する名前付き定数を使用してください。

これらの目標は両方とも、構成ファイルを必要とせずに達成できます。実際、可能であればそれらを避けたいと思います。「構成ファイルに何かを入れると、変更が容易になる」というのは神話です。

  • 実際に顧客自身が価値観を変えるのをサポートしたい
  • 設定ファイルに入れられる可能性のある値は、バグを引き起こす可能性があります (バッファオーバーフロー、誰か?)
  • あなたのビルドと展開のプロセスは最悪です
于 2008-12-31T16:46:52.793 に答える
3

あなたの2番目が本当にハードコーディングの例だとは思いません。これは、除算に使用する値を受け取る Halve() メソッドを持つようなものです。意味がありません。

さらに、例 1 のように、アプリの言語を変更したい場合、クラスを変更する必要はありません。したがって、それは絶対に構成に含まれている必要があります。

ドラキュラが太陽を避けるように、ハードコーディングは避けるべきです。最終的にはお尻を噛むために戻ってきます。

于 2008-12-31T00:29:04.483 に答える
2

番号。

今日の単純な使い捨てアプリは、明日の企業全体を推進します。常にベスト プラクティスを使用してください。そうしないと、後悔することになります。

于 2008-12-31T04:40:40.620 に答える
2

通常ではありません (ハードコーディングされたリテラルは受け入れられますか)

これを見る別の方法は、ハードコードされたリテラルの代わりに使用される定数に適切な命名規則を使用することで、プログラムに追加のドキュメントを提供する方法です。

番号が 1 回しか使用されていない場合でも、認識が難しく、将来の変更のために見つけるのが難しい場合もあります。

私見ですが、プログラムを読みやすくすることは、経験豊富なソフトウェアの専門家にとって当たり前のことです。生の数値が意味のある通信を行うことはめったにありません。

適切な名前の定数を使用するために余分な時間がかかるため、コードが読みやすくなり (思い出すのが容易になります)、将来のリマイニング (コードの再利用) に役立ちます。

于 2009-02-10T04:44:17.980 に答える
2

条件のテキストはリソース ファイルにある必要があります。それが目的です。

于 2008-12-31T01:08:40.737 に答える
1

コードは常に進化します。最初に何かを書くときは、ハードコーディングが最も簡単な方法です。後で値を変更する必要が生じたときに、それを改善することができます。場合によっては、必要が生じることはありません。

ニーズはさまざまな形で到着する可能性があります。

  1. 値は多くの場所で使用されており、プログラマーが変更する必要があります。この場合、定数が明らかに必要です。

  2. ユーザーは値を変更できる必要があります。

ハードコーディングを避ける必要はないと思います。明確な必要性があるとき、私は物事を変える必要があると思います。

まったく別の問題は、もちろんコードが読み取り可能である必要があるということです。これは、ハードコードされた値に対するコメントが必要になる可能性があることを意味します。

于 2008-12-31T16:16:02.120 に答える
1

私は、プロジェクトの範囲と規模の観点からそれを見る傾向があります。

私が単独で開発しているいくつかの単純なプロジェクトはありますか? 確かに、私は多くのことをハードコーディングしています。私が書いた、私だけが使うツール?もちろん、それが仕事を成し遂げるなら。

しかし、より大規模なチーム プロジェクトに取り組む場合はどうでしょうか。私は同意します、それらは疑わしいものであり、通常は怠惰の産物です. それらにタグを付けてレビューし、それらを抽象化できるパターンを見つけられるかどうかを確認してください。

あなたの例では、テキスト ボックスはローカライズ可能である必要があります。

于 2008-12-31T00:28:47.853 に答える
1

明らかでないハードコードされた値の意味を忘れてしまうことに注意してください。

そのため、思い出させるために、それぞれの後に短いコメントを必ず入れてください.

Delphi の例:

長さ:= 長さ * 0.3048; { 0.3048 はフィートをメートルに変換します }

于 2008-12-31T00:32:46.113 に答える
1

リファクタリング、単体テスト、ピア コード レビューを行わなければ問題ありません。そして、あなたは繰り返し顧客を望んでいません。誰も気にしない?

于 2008-12-31T00:40:17.533 に答える
0

私は通常、文字列と数値のヘルパーメソッドのセットを追加します。

たとえば、「yes」や「no」などの文字列がある場合、__という関数があるので、__('yes');を呼び出します。これはプロジェクトで最初のパラメーターを返すだけで始まりますが、より複雑なこと(国際化など)を行う必要がある場合は、すでにそこにあり、パラメーターをキーとして使用できます。

もう1つの例は、オンラインショップのVAT(英国税の形式)です。最近、17.5%から15%に変更されました。次のようにしてVATをハードコーディングした人。

$vat = $price * 0.175;

次に、すべての参照を調べて0.15に変更する必要がありました。代わりに、VATの関数または変数を使用するのが非常に便利です。

私の意見では、変更される可能性のあるものはすべて、変更可能な方法で作成する必要があります。同じ日に5回以上同じことをしていることに気付いた場合、それは関数または構成変数になります。

于 2008-12-31T16:33:06.267 に答える
0

私はかつて、ソフトウェアとソフトウェアに関連するアイテムを完全に制御できるようになったので、何かをハードコーディングしないことを拒否した上司がいました。問題は、ソフトウェアを実行していたハードウェアが故障したときに、サーバーの名前が変更されたことでした... つまり、彼は自分のコードを見つけなければなりませんでした。それにはしばらく時間がかかりました。私は単純に 16 進エディタを見つけて、待つ代わりにハッキングしました。

于 2008-12-31T02:16:42.113 に答える
0

ハードコーディングは永久に禁止されるべきです。非常に単純な例ですが、どのような種類のプロジェクトでもそれらを使用しても問題はありません。

私の意見では、ハードコーディングとは、変数/値/定義などは決して変更されず、その信念に基づいてすべてのコードを作成すると信じている場合です。

そのようなハードコーディングの例は、誰もが避けるべきである Teach Yourself C in 24 Hours です。

于 2008-12-31T15:09:40.540 に答える
0

最初の値については、実際に依存します。あなたのアプリケーションが広く採用されることを予期せず、国際化が問題にならないのであれば、ほとんど問題ないと思います。ただし、ある種のオープン ソース ソフトウェアやより多くのユーザーを対象としたものを作成している場合は、いつか翻訳が必要になる可能性があるという事実を考慮してください。その場合、文字列リソースを使用した方がよい場合があります。

于 2008-12-31T00:32:42.727 に答える