SERVICES


要約

サービスって何だろ

  • entityとかvalue objectに振る舞いもつけられるけど、振る舞い自体オブジェクトとして切り出す検討もしたほうがいいよね。オブジェクト的でない振る舞いってあるし。
  • entityとかvalue objectにやたら振る舞いを持たせるのは典型的な誤り。複雑な振る舞いをentityとかvalue objectに持たせると、責務がぶれたりする。
  • ドメインは自然に現れるドメインだけではなく、人工的に作った概念も含まれるよ。
  • いけてるサービスは、1. entityとかvalue object近い概念の振る舞いを実装してる、2. ドメインっぽい名前でインターフェイスを切ってる、3. ステートレスに実装する、という条件を満たしている

サービスと、独立したドメインレイヤー

  • サービスもドメインのレイヤーだけで使用されるわけではないので、区別して理解しておいたほうがいいですね。
アプリケーションレイヤーアプリケーションの機能を提供するためのサービスレイヤー。例だと、預金口座の内容をspreadsheetに展開するサービス。
ドメインレイヤーエンティティとかビジネスサービスなどの業務ロジックを提供するサービスレイヤー。例だと、預金口座の振込み機能を提供するサービス。
インフラレイヤー通信とかメッセージングとか、基盤フレームワークを提供するサービスレイヤー。例だと、emailの送信機能を提供するサービス。
  • ファサードとなるコントローラーがこいつらを組み合わせて機能を提供すると見やすいかも。

粒度の問題

  • サービスについては、entityとかvalue objectと異なる粒度を持っていてもいいかも
  • ドメインオブジェクトの粒度が細かすぎると、アプリケーションレイヤーにドメインの知識が浸潤してしまうので、サービスを使ってうまくドメインオブジェクトを結びつける
  • サービスがドメインの概念をもっともよく表現することもある

サービスに対するアクセス

  • インターフェイス経由にしておけば問題ないと思います

担当者のつぶやき

  • 僕がいま所属しているプロジェクトでは、business.domainパッケージを切ってそこにentity/value objectを置き、business直下にserviceとなるインターフェイスを置いています。(business.implに実装を配置)。別途ユースケース固有の実装を置くfacadeパッケージもある。
  • サービスとエンティティを分離できる設計なんてできるの?ドメインを持つアプリケーションからドメインを抜いたらコンパイル通るわけが。。。
    • 依存関係逆転の原則とかでがんばればどうにかなるかもしれないですね。でもアプリケーション固有なドメインなら努力する価値が。。。
  • エンティティ/サービスに実装する振る舞いの切り分けとしては、戻り値がエンティティの保持する変数/保持する変数からの導出項目となるか、エンティティとなるか、あたりが使えるかも知れないと思いました
  • active record全否定ではないですが、ドメインの知識=エンティティのプロパティ的な発想は結合テストとか保守の工数を考慮すると単なるアンチパターンのように思います
  • 人工的なドメインというのは多分、アナリシスパターンで出てくるlegとか、aggregationの仲介役となるようなやつらですね。実際のドメインモデルでも、legとかhogehogeAttributeとか、ドメインをうまく取り扱えるようにするやつらを見かけます。(entityとかvalue objectの話ですが)

みんなの突っ込み


まとめ