あかね
新キャラ「ドメインオブジェクト」
2026年07月15日
要約を生成中...
仕事でRailsを日々扱ってるんですが、いまだに「これ、どこに書くん?」って悩んでます。
Railsはオブジェクト指向なので、凝集度をとても意識します!!
凝集度とは
関係あるもの同士を一か所にまとめられてるか??ってことです!
「このバリデーションはモデルに書くべき?」
「いや業務ロジックかな、、じゃあサービスクラス?」
「業務ロジックだけどちょっと責務違うくない?じゃあ別クラス?」
「共通処理だからモジュール…?」
で、今日また新しいのが出てきました。
ミノ駆動さんのskillを入れて、実行してみたら初めて言われて驚き。
ARではないモデルみたいなオブジェクト、、、、何それ???
今までプロジェクト内でも私はやったことなくて、でも既存で1つだけあってこれは慣習的にどうなんだろって感じで。
実務、ECやってるのでとにかく「計算処理」がよく出てきます。
最初は素直に「サービスクラスに書けばええやろ」くらいのノリでした。
クラスが肥大化してたら責務疑う、純粋関数みたいなのはテストしやすいしモジュールにするくらいの意識でした。
でも要件が増えてくると、だんだん変な感じになってくるんですよね。
この計算結果、別の場所でも使いたい
同じ考え方を複数のサービスで扱ってる
そもそも「価格」って概念そのものを持ち回したい
ここで、
「…これここに書くの正解なんかな?」
ってなったんですよねぇ
葛藤です。
サービスクラスに書いてると重複する処理が出てきます。
ECなので、カート、チェックアウト画面、注文処理、同じ計算を結構したりします。
ここはDRYで行きたい。じゃあどうする???ActiveRecord のモデルに書く??でも、他で使わないから結構業務ロジックっぽいんだよな。。。みたいなことが起きます。
単なる計算結果でもないからモジュールでもない。。?どれとっても微妙な気がする。。。
例えば「価格」っていう、業務上ちゃんと意味を持ってるけど「税込価格」って概念になるとちょっとそれが必要な場面は限定的だったりするので、モデルでいいのか??みたいな。
このモヤモヤの置き場所がなくていちいち悩んでました。
この話に関しては最初は「2か所以上で使うしDRYにしたいな〜」くらいの感覚だったんです。
でもレビューでやり取りしてるうちに、本質そこじゃないなと気づいたんです。
同じ「価格」って概念を複数の場所で扱うなら、「価格とは何か」っていう知識を一か所に集めたい。これなんですよね。
DRYにしたいんじゃなくて、業務知識を一か所に集約したい。その結果としてDRYになる。
順番が逆だったな、って感じで。
今の頭の中こんな感じ。
モデル …永続化されるエンティティ自身が持つ責務。外から隠蔽したい(外から知る必要のないクラス内に収まるべき)処理を書いたりもするけど、かなり汎用的なものに限る
サービスクラス … 手続き系業務ロジックがあるクラス。責務増えたらさらに分けることもある。
モジュール … 状態を持たない共通処理。TSでいうただの関数みたいなやつ
ドメインオブジェクト … ActiveRecordじゃない。でも業務上の「モノ」として意味を持ってるオブジェクト。複数のサービスで同じ概念を扱い始めたときの、知識の置き場所。
今回のは正確には「値オブジェクト」。ドメインオブジェクトの一種らしい
これまでは
モデル
サービスクラス
フォームオブジェクト
コントローラー
シリアライザー
くらいだったのに、新キャラ出てきて困惑した今日でした。
これどこにあるべきなんだ??は毎日考えてます、、!むずい、、、ってか正解はなくて人の思想やプロジェクトによるルールもあるし難しいなって思います。
新しい設計の考え方を1個ずつ知っていくってのはほんとに大事なことですね。
今回はそれが「ドメインオブジェクト」でした。
「サービスに書くか迷う」「モデルでもない」「複数箇所で同じ業務概念を扱ってる」このモヤモヤに対してそういう置き場所あるんだ〜って知れたのが、今日いちばんの収穫です。
Rails好きじゃない部分もありますが、モデルって概念はすごく好きで(これは保存させないってバリデーション的制御をアプリケーション層でできたり、Hoge.hogeって内部のこと知らなくても何できるかわかるようなメソッドの定義ができたり。便利です)、オブジェクト指向にもだいぶ慣れてきた気がします。
でもこれどこに書くのが正解??って悩みは毎日続いています!!
ここかここか悩んでるって相談することもありますが、悩ましいですねぇって言われつつ自分の意見はこう!みたいなフィードバックをもらったりするので、これ以外正解ないってパターンだけじゃないので観点をとにかく増やしていきたいなって思います!!
要約
コメント
まだコメントはありません。