まえおき
そんな大したものではないけど、自分なりの設計のやり方みたいなのを整理して文書化したいなみたいな気持ちがある
— やんく✌('ω')✌ (@yy_yank) March 23, 2024
無意識で良しとしてやってることが多すぎるので
というわけで「俺のプログラミング」シリーズです。 自分が何を大事にしてプログラミングをしているか、自分でもよく分かってないので思いついたものを書いていく予定です。 今回はドメインオブジェクトについて。
ドメインもどき
なんかしら、「ドメイン」と名のつくものを量産すること避ける。
例えば IntやString、Optionなど生(raw)っぽい型を引数に取るhogeFugaメソッドなどがある場合、 とりあえずHogeFugaXXX型などを作るようなものはよく考えたい。 それは言ってしまえば「ドメインもどき」かもしれない
意味の薄いwrapperだらけになってない?
DTOとしてメソッド単位で割り切るならまだしも、 ドメインオブジェクトとして、HogeFugaName型、HogeFugaEmail型とか安直に作ると面倒なことになる。 (DTOも何も考えないで詰め込むことになりがちなので好きではないけど) 「これでメソッドの引数を間違えることがない」 「型安全だ」みたいなことを言われると、 せやかて工藤という気持ちになる。 結局、IntやStringのwrapperをメソッド単位に量産することになり、 それは一体ドメインと言えるものなのか?というところがある。 極端な話、例えば
hogeFuga(String arg1, String arg2)
という関数があった場合、 取り間違えを避けるために
hogeFuga(HogeFugaArg1 arg1, HogeFugaArg2 arg2)
としていることが多いという話。 Arg1やArg2の意味を考えられてないので、 設計次第では結局、Arg1とArg2に入れる値を間違えてしまうかもしれない。 専用の皿をそれぞれ作ったとしても、乗っているのが常に同じおかずとは限らないみたいな話。
そういう余分な複雑性を生むのであれば、 生(raw)のIntやStringの方がマシな時もある、かもしれない。 値を限定するのであれば、Enumや代数的データ型、直和型的なアレでスコープを絞るのが良さそう。こいつはドメインと呼べるのかな。どっちかというと値型に制約をつけているだけみたいなイメージがある。
業務の領域ごとにドメインを考える
hogeFugaを取っ払って、Name型とかEmail型とか作る方が良いのかもしれない。
だけど、かなり汎用の型になってしまい、
色々なところでその型を使い回すことになり面倒になったりもする。
ニーズが増え出すと付け足し付け足し秘伝のタレになっていくかも。
業務Aの場合のEmailと業務Bの場合のEmailで役割や意味が違うといった場合を意識して型も分ける必要がある。
メソッド起点にドメインを作らない
大事なのは、メソッド単位ではなく、役割というか業務ごとに考えるという感じかもしれない。ユースケース単位で考えるのも止めたほうが良い気がする。 ここまで書いて思うのは、ドメインオブジェクトを作る時に、メソッドが起点になってはいけないということ。ドメインの主体は、あくまでドメインということ。
俺達は雰囲気でドメインオブジェクトをやっている
あと、単純にドメインという言葉もあんまり好きではないかもしれない。ドメインといった場合に各メンバーが定義しているものがバラバラであることが多いので。
僕が思っているドメインは、なんとなく
概念や性質を表現して振る舞いを持つこともあるもの=ドメインオブジェクトかもしれない。
どういう振る舞いを持つかどうかは諸説ある気がするけど、僕はそこまで何か厳密には考えられていない。
ファウラーおじさんによると以下とのこと。
ビジネスのコンセプト、ビジネスの状況に関する情報、 およびビジネスルールを表現する責務を負います。 これを保存する技術的な詳細はインフラストラクチャに委譲されるものの、 ビジネスの状況を反映する状態はここで制御され、使用されます。 この層は業務ソフトウェアの心臓部です。
まとめ
- ドメインを作りすぎない
- ドメインを業務ごとに使い分け出来るようにする
- 単純に、引数の型の誤りとかを避けたいのであればDTOにでもして逃げる(適切なドメインを定義できていない場合)
- 引数の値がパターン化されているものは、Enumや代数的データ型などで定義しておく
- 安易にドメイン型を作ってしまうぐらいなら、バリデーターやファクトリなどで保証したほうが良いかもしれない(実行時チェックにはなってしまうが)
- バリデーターやファクトリを作っているうちに、各所で「ドメインらしさ」が分かってきたりしたらドメインオブジェクトを作るチャンスかもしれない
参考
https://www.playframework.com/documentation/ja/1.2.x/model https://bliki-ja.github.io/AnemicDomainModel
0 件のコメント:
コメントを投稿