文字列を定数として宣言すべきパターン

たとえば、文字列リテラルをそのまま使用せずに、定数として宣言して使用した場合と

private const string SQL = "SELECT * FROM table1 WHERE id = @id";

private const string ID_PARAM_NAME = "@id";

public Record GetRecord(int id)
{
    return ExecuteSql(
               SQL,
               new Dictionary<string, object>
               {
                   { ID_PARAM_NAME, id }
               });
}

定数として宣言せずにそのまま書いた場合で

public Record GetRecord(int id)
{
    return ExecuteSql(
               "SELECT * FROM table1 WHERE id = @id",
               new Dictionary<string, object>
               {
                   { "@id", id }
               });
}

私(今現在)は、可読性を考えて後者のような書き方をする場合が多いのですが、パフォーマンス的な観点からなのか、なんでも定数として宣言したうえで使うべきと考える人もいます。(私も昔そんな時期がありました…)

人やプロジェクトによって、優先すべきものが違うので、一概にこれが正しいというのは無いと思っていますが、、定数として宣言してから使うことになると、コード上で見なければならない箇所が増える(すぐ近くで宣言されてればまだいいですが)ので、コードの可読性が下がるというデメリットがあると思ってます。
(似たような話で、ローカル変数の宣言と、最初に使用する箇所が離れているようなのも、可読性を下げる要因かと)


今のところ、自分の中では、文字列を定数として宣言して使うべき箇所は、下記のように考えています。

  • その文字列を、同じ意味/意図で複数個所で使う場合
    • 1箇所にまとめておいたほうが、変更漏れが防げて、メンテナンス性が高くなる
  • その文字列が、文字列だけでは意味を読み取れない場合
    • たとえば"xyz"という文字がそのまま書かれていても、なんのための文字列だかわからない。それを定数として宣言し、変数名から何を表すものなのか読み取れるようにする。

上記以外は、必ずしも定数として宣言する必要はない(逆に、定数として宣言してから使うことにより、可読性が落ちる場合がある)と思ってます。


あと、ヒアドキュメントが使えない言語(Java)は、複数行に渡るような文字列の宣言がしずらい(読みやすく書けない)ので、早くそういった仕組みを取り入れて欲しいですね!