リテラルとはソースコードに定義された値のことを指します。
たとえば以下の場合、変数fruit
に定義されたapple
はリテラルとなります。
string fruit = "apple";
リテラルはなるべく定数化した方がいいです。
"apple"くらいならソースを見て内容を理解できなくもないですが問題は以下のようなケース。
いわゆるマジックナンバーと呼ばれるケースです。
// divisionを取得
int division = $this->getDivision();
// divisionによって条件分岐
if (division == 1) {
// division == 1 の処理
} elseif (division == 2) {
// division == 2 の処理
} elseif (division == 3) {
// division == 3 の処理
}
プロジェクトの規模が大きくなるほど自分の把握できていない処理が増えてくると思います。
そうなるとマジックナンバーは元の処理を辿らないと理解しづらくなり、改修などに時間を要してしまいます。
無駄な時間を省くためにも定数化はなるべく行いましょう。
定数化のサンプル
PHPで定数化する場合の一例を紹介します。
先ほどのマジックナンバーで使用したdivision
用の定数ファイルを作成します。
/** 状態 */
class Division
{
/** 停止中 */
public const DIVISION_STOP = 1;
/** 起動中 */
public const DIVISION_START = 2;
/** 稼働中 */
public const DIVISION_RUN = 3;
}
次にマジックナンバーを定数化してみましょう。
単にdivision == 1
とするよりは可読性が上がったと思います。
// divisionを取得
int division = $this->getDivision();
// divisionによって条件分岐
if (division == Division::DIVISION_STOP) {
// division == 1(停止中) の処理
} elseif (division == Division::DIVISION_START) {
// division == 2(起動中) の処理
} elseif (division == Division::DIVISION_RUN) {
// division == 3(稼働中) の処理
}
目先の実装速度を優先するあまりリテラルに走りがちですが、キチンと定数化をすれば可読性や保守性が上がり長期的に得られるメリットは大きいです。
この記事が脱ハードコーディングのきっかけになれば幸いです。
余談
定数化ファイルとクラスファイルは分けるケースが多いと思いますが、そのクラスでしか参照されないような定数である場合はクラス内でprivate
に定数化してもいいと思います。
サンプルで紹介した処理がログイン機能で呼ばれるとした場合は以下のようになるでしょう。
/**
* ログイン機能
*/
class Login
{
/** 停止中 */
private const DIVISION_STOP = 1;
/** 起動中 */
private const DIVISION_START = 2;
/** 稼働中 */
private const DIVISION_RUN = 3;
/**
* 初期化
*/
public function init()
{
// divisionを取得
int division = $this->getDivision();
// divisionによって条件分岐
if (division == Division::DIVISION_STOP) {
// division == 1(停止中) の処理
} elseif (division == Division::DIVISION_START) {
// division == 2(起動中) の処理
} elseif (division == Division::DIVISION_RUN) {
// division == 3(稼働中) の処理
}
...
}
/**
* 状態を取得
* @return int 状態
*/
public function getDivision() :int
{
...
}
}