Formatterを分けておくと助かる話
LaravelでViewModelを書いていると、
つい「ここで number_format() すればいいか」と思って書いちゃうこと、ありますよね。
最初はそれで十分。
でも、気づくと同じフォーマット処理があちこちに散ってる。
- 価格の書き方がViewごとに微妙に違う
- nullチェックが重複している
- 日付の整形が毎回コピペ
- Bladeにもフォーマットが混ざってくる
そうなると、「どこを直せば全部直るのか」分からなくなってきます。
そこでようやく、“Formatter”の出番が見えてきました。
Formatterって何者?
ざっくり言うと、
表示のための整形ロジックをひとまとめにする小さな道具箱。
ロジックを持たないDTOと、見せ方を担当するViewModel。
その中間で、「整形そのもの」を分離するのがFormatterの役割。
たとえばこんな感じです。
final class PriceFormatter
{
public static function range(int $min, int $max): string
{
if ($min && $max) return number_format($min) . '〜' . number_format($max) . '円';
if ($min) return number_format($min) . '円〜';
if ($max) return '〜' . number_format($max) . '円';
return '—';
}
}ViewModelではもう、
$label = PriceFormatter::range($r->monthlyPriceMin, $r->monthlyPriceMax);と書くだけ。
この一行で、フォーマットを一括で管理できるようになります。
こんな感じでViewModelで表示処理が終わるので、
bladeに行く段階ではただ変数を表示するだけというスッキリ構造。
どうして分けておくと助かるのか
最初のうちは「ファイルが増えるだけ」と思っていたけど、
Formatterを導入してみたら地味な快適さがありました。
1. ViewModelが静かになる
フォーマットが消えると、ViewModelが「値の流れ」だけになる。
Blade側も読みやすくなる。
2. 修正の範囲が明確になる
「価格の表記を“円/月”に変えたい」みたいなとき、
PriceFormatterを1か所直せば全部変わる。
3. テストしやすい
Formatterは状態を持たない静的クラス。
入力と出力だけを比較できて、テストが軽い。
まとめ
Formatterって、アーキテクチャ的に派手な層ではないけど、
入れておくとコード全体のテンポが良くなりました。
DTOとViewModelを分けたあとの最後の整理整頓みたいな存在。
これがない時はモデルとbladeで結局ぐちゃぐちゃになりがちでしたが、
導入したことでかなりスッキリ行っています。
「どこで整形するか」を決めてあげるだけで、
コードの流れがずっと静かになるんですね。
今回は以上です!