1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

リテラルは必ず定数にしてほしい

Posted at

今回はリテラルの扱い方について書いていこうと思います。
リテラルは初学者から扱うことが極めて多いものです。

教科書の Hello World でいきなり使います。

ですが、こいつの扱いがザツなことが多いですね。

リテラルは出現回数が1回でも定数にせよ

リテラルとは次の "bust" などのことを言います。

悪い例

sample.java
/** データベースから name のスリーサイズをmapで返却 */
public static Map<String, Integer> getThreeSize(String name){
    ThreeSizeDto threeSizeDto = threeSizeDb.getThreeSize(name);
    Map<String, Integer> retValue = new HashMap<>();
    retValue.put("bust", threeSizeDto.getBust());
    retValue.put("west", threeSizeDto.getWest());
    retValue.put("hip", threeSizeDto.getHip());
    return retValue;
}

/** スリーサイズのmapを生成 */
public static Map<String, Integer> setThreeSize(Integer bust, Integer west, Integer hip){
    Map<String, Integer> retValue = new HashMap<>();
    retValue.put("bust", bust);
    retValue.put("west", threeSizeDto.getWest());
    retValue.put("hip", threeSizeDto.getHip());
    return retValue;
}

public static void main(String[] args){
    Map<String, Integer> threeSizeMap = getThreeSize(args[0]);
    System.out.println(args[0] + "さんのバストサイズは" + threeSizeMap.get("bust"));
}

これセットする側も参照側も同じこと書いてますよね。

人間がプログラムを追ってみれば、"bust"とは、threeSizeDto.getBust() を表しているとわかりますが、追わないとわからないんですよ。
追わせないでください。 時間の無駄です。

これを定数にすることで、定数から意味を知ることができます。

##良い例

sample.java
/** 定数 */
public class Constants {
    /** スリーサイズのバスト */
    public static final String KEY_THREE_SIZE_BUST = "bust";
    /** スリーサイズのウエスト */
    public static final String KEY_THREE_SIZE_WEST = "west";
    /** スリーサイズのヒップ */
    public static final String KEY_THREE_SIZE_HIP = "hip";
}

/** データベースから name のスリーサイズをmapで返却 */
public static Map<String, Integer> getThreeSize(String name){
    ThreeSizeDto threeSizeDto = threeSizeDb.getThreeSize(name);
    Map<String, Integer> retValue = new HashMap<>();
    retValue.put(KEY_THREE_SIZE_BUST , threeSizeDto.getBust());
    retValue.put(KEY_THREE_SIZE_WEST , threeSizeDto.getWest());
    retValue.put(KEY_THREE_SIZE_HIP , threeSizeDto.getHip());
    return retValue;
}

/** スリーサイズのmapを生成 */
public static Map<String, Integer> setThreeSize(Integer bust, Integer west, Integer hip){
    Map<String, Integer> retValue = new HashMap<>();
    retValue.put(KEY_THREE_SIZE_BUST , bust);
    retValue.put(KEY_THREE_SIZE_WEST , threeSizeDto.getWest());
    retValue.put(KEY_THREE_SIZE_HIP , threeSizeDto.getHip());
    return retValue;
}

public static void main(String[] args){
    Map<String, Integer> threeSizeMap = getThreeSize(args[0]);
    System.out.println(args[0] + "さんのバストサイズは" + threeSizeMap.get(KEY_THREE_SIZE_BUST ));
}

こうすることで、リテラルの直記載では得られなかった 「意味のつながり」 が表現されます。
getThreeSize と setThreeSize で、定数を共有しているため、全く同じ意味の map であることが表現されます。

※Javaをちゃんとやっている人にとっては「そんなの、ちゃんと部品共通化すればいいじゃん」という声もあろうかと思いますが、それでも部品が拡張されたときのことを考えれば、すべてを定数にするほうが、将来的に良いと私は確信しています。

#定数にするメリット・デメリット
##メリット

  • mapキーに共通の意味のつながりを持たせることができる(ServletRequest で多用されますね)
  • 定数からIDEで使用箇所をたどることができる(マイグレーションで大活躍)
  • 変更耐性が強い(拡張時に、定数だけ変更すればよいケースが多い)

##デメリット

  • コード量が多くなる(単純にめんどくさい)

メリデメだけを見ても、やって損はないと思います。

#まとめ:リテラル書いたら、定数にしよう
リテラルを書く機会って、本当にたくさんあります。
現代のプログラムは、ほとんどがフレームワークで作られます。
フレームワークでは、データにキー値で意味づけすることが多く、早く作れるので、都度都度リテラルを書いてしまいがちです。

ぜひリテラルをロジック中に書くことになったら、定数にすることをおススメします。
この説明だけで、そのメリットが十分に伝わっていなくても、近くきっとあなたにとって、 「やっててよかった」の瞬間があるはずです。

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?