Formatterを分けておくと助かる話

2025.10.24 09:00
2025.10.21 21:54
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で結局ぐちゃぐちゃになりがちでしたが、
導入したことでかなりスッキリ行っています。

「どこで整形するか」を決めてあげるだけで、
コードの流れがずっと静かになるんですね。

今回は以上です!