[Laravel]定数(const)はどこに書くべきか?チーム内でやる場合のおすすめのマジックナンバー対処方法
Webアプリケーションを開発する上で、気を付けべきことにマジックナンバーがあります。
個人で開発であればさほど意識されない人もいますが、チームだとマジックナンバーは必ず認識合わせしておく必要があります。
今回Laravelでマジックナンバーでの対処方法を紹介します。
そもそもマジックナンバーって何?
マジックナンバーについて簡単に説明すると「何を指しているかわからない数字や文字列」です。
プログラムにおけるマジックナンバー(英: magic number、魔法の数字)とは、何らかの識別子もしくは定数として用いられる、プログラムのソースコード中に書かれた具体的な数値である。そのプログラムを書いた時点では製作者は数値の意図を把握しているが、他のプログラマーまたは製作者本人がマジックナンバーの意図を忘れたときに閲覧すると「この数字の意味はわからないが、とにかくプログラムは正しく動く。まるで魔法の数字だ」という皮肉を含む。
引用:wiki
チームで開発を進めると自分自身では意味ある数字や文字列だけど、他人から見ると何を指しているかわからない事象がおこります。
よくありがちなソースコードで説明します。
class Order
{
public function update($status)
{
if ($status === 1) {
// ステータスが1の場合の処理
}
if ($status === 2) {
// ステータスが2の場合の処理
}
// 保存処理
}
}
上記のソースを見ると、ステータスの「1」って何?「2」は何?と何を指しているかわかりませんよね。
注文受付なのか、キャンセルなのか、返品なのか、他にどんなステータスが存在するのかわかりません。
このステータスの意味を理解するには、ソースコードを解読するか開発した本人に聞くしかありません。非常に非効率な開発の仕方です。
Laravelでマジックナンバーを解決する
マジックナンバーを解決する方法として、やり方が複数ありますので代表的なものだけ紹介します。
configファイルで定数を管理する
定数となるものをconfigファイルに持たせてしまおうという方法があります。
個人的にはおすすめしないですが、やり方としてよく見る方法なので紹介しておきます。
<?php
return [
'orders' => [
'status' => [
'recept' => '1',
'sent' => '2',
'cancel' => '3'
],
'status_list' => [
'1' => '注文受付',
'2' => '発送済み',
'3' => 'キャンセル'
],
],
];
コントローラーなどの処理
public function store(Request $request)
{
if($request->status == config('const.orders.recept')){
// 処理
}
// insert
User::create(['status' => config('const.orders.recept')]);
}
viewの処理
<div class="form-group form-inline mt-2">
<div class="form-inline">
@foreach(config('const.orders.status_list') as $key =>$val)
<div class="form-check mr-2">
<label class="form-check-label">{{Form::checkbox('status[]', $key,old('status')))}}{{$val}}</label>
</div>
@endforeach
</div>
</div>
上記のようにconfigファイルにしてconstを定義して呼び出すことでマジックナンバーを回避することができます。
しかし、私がおすすめしない理由があります。
- configファイルにまとめると肥大化します。ファイルを分けしてもconfigファイルが大量にできて管理しづらくなる。
- 「config('const.orders.recept')」と記述しても、定数ファイルに定義へ移動(Ctrl+クリック)することができません。
英語が苦手な人は「recept」の意味が分からず、定数ファイルをいちいち確認する手間が出てしまいます。
Modelクラスファイルに定数を記述する
こちらもよくある方法ですね。モデルのクラスに定数ファイルを書く方法ですね。
class Order extends Model
{
const STATUS_RECEPT = '1';
const STATUS_RECEPT_NAME = '注文受付';
const STATUS_SENT = '2';
const STATUS_SENT_NAME = '発送済み';
const STATUS_CANCEL = '3';
const STATUS_CANCEL_NAME = 'キャンセル';
const STATUS_LIST = [
self::STATUS_RECEPT => STATUS_RECEPT_NAME,
self::STATUS_SENT => STATUS_SENT_NAME,
self::STATUS_CANCEL => STATUS_CANCEL_NAME
];
}
viewの処理
<div class="form-group form-inline mt-2">
<div class="form-inline">
@foreach(App\Models\Order::STATUS_LIST as $key =>$val)
<div class="form-check mr-2">
<label class="form-check-label">{{Form::checkbox('status[]', $key,old('status')))}}{{$val}}</label>
</div>
@endforeach
</div>
</div>
テーブルの定数のだからModelに書いてあげることで分かりやすくなりました。また、定数から定義へ移動(Ctrl+クリック)することもできます。
ですが、こちらもおすすめできない理由があります。
- Modelクラスは親クラスを継承していたりDB接続したりで使用するため定数呼ぶだけのためにModelを呼び出すのはいまいち
- Modelを使わない定数はどうするか、定数用のModelファイルを作るのはいまいち
専用のConstクラスファイルを作成する
個人的におすすめな方法が、専用のConstクラスファイルを作成する方法です。
毎度ファイルを作成するのが手間ですが、管理がシンプルで使いやすいです。
<?php
namespace App\Consts;
class OrderConst
{
const STATUS_RECEPT = '1';
const STATUS_RECEPT_NAME = '注文受付';
const STATUS_SENT = '2';
const STATUS_SENT_NAME = '発送済み';
const STATUS_CANCEL = '3';
const STATUS_CANCEL_NAME = 'キャンセル';
const STATUS_LIST = [
self::STATUS_RECEPT => STATUS_RECEPT_NAME,
self::STATUS_SENT => STATUS_SENT_NAME,
self::STATUS_CANCEL => STATUS_CANCEL_NAME
];
}
viewの処理
<div class="form-group form-inline mt-2">
<div class="form-inline">
@foreach(App\Consts\OrderConst::STATUS_LIST as $key =>$val)
<div class="form-check mr-2">
<label class="form-check-label">{{Form::checkbox('status[]', $key,old('status')))}}{{$val}}</label>
</div>
@endforeach
</div>
</div>
また、スタッフが操作する画面には選択できるステータスを絞りたいといったことがあります。
そういった場合は、スタッフ用のステータスリストを作成してあげます。
<?php
namespace App\Consts;
class OrderConst
{
...
// スタッフ変更可能ステータス
const STUFF_STATUS_LIST = [
self::STATUS_RECEPT => STATUS_RECEPT_NAME,
self::STATUS_SENT => STATUS_SENT_NAME,
];
}
このように記述することができます。
さいごに
今回チーム開発で課題になってくるマジックナンバーの対処方法についていくつか紹介しました。
個人的には専用のConstクラスファイルを作成する方法がしっくりきておすすめしたいですが、結局はチーム内でやりやすいかどうかだと思っていますので、参考程度にとらえていただけると嬉しいです。
コメント
コメントを残す