Various Services

Various Services

Martin Fowler の PofEAA や Eric Evans の Domain-Driven Design に登場する “サービス” と呼ばれるものたちについて整理し、然るべきタイミングで活用したいというモチベーションで調べた内容。

E39aeab4407ea02102f75584618549a4?s=128

Hibariya Hi

May 18, 2017
Tweet

Transcript

  1. Various Services 2017/05/18 まっちまLT

  2. Hello • Gentaro Terada (@hibariya) • PofEAA 勉強会に参加中 • カンディンスキー好きー

  3. TIL

  4. モチベーション Martin Fowler の PofEAA や Eric Evans の Domain-Driven

    Design に登場する “サービス” と呼ばれるものたちについて整理 し、然るべきタイミングで活用したい。ある日突然 XXService にエ ンカウントしたときに向き合えるようにしておきたい。
  5. TL;DR • サービスには色々ある。 • PofEAA のサービスレイヤと DDD 本のサービスは別物。 • サービスレイヤはドメインロジックとアプリケーションロジックが

    混ざらないようにするための層。 • ドメインサービスは既存のオブジェクトに属せない操作をサー ビスというかたちでドメイン層に定義したもの。 • 導入にはトレードオフがある。
  6. サービスはどこにあるか

  7. サービスはどこにあるか

  8. どこにでもある

  9. 文脈による

  10. サービスはどこにでもある “サービス” はどこにでもあって、文脈によって違う。 • 振込処理を行う (ドメイン層) • メールなどで通知する (インフラストラクチャ層) •

    帳票をCSVでエクスポート (アプリケーション層) • サービスレイヤ (ドメイン層の上にある薄い層)
  11. サービスレイヤ

  12. サービスレイヤ

  13. ドメインロジックを守るレイヤ “... But putting application logic into pure domain object

    classes has a couple of undesirable consequences. First, domain object classes are less reusable across applications if they implement application-specific logic and depend on application-specific packages. ...” PofEAA p.134 “How It Works”
  14. “ビジネスロジック” の内訳 • ドメインロジック: 純粋にドメインの問題を解決する。 • アプリケーションロジック:メール通知のような、ドメインロジック ではないアプリケーション固有のロジック。

  15. サービスレイヤ ドメインロジックとアプリケーションロジックを切り離すための薄い 層。ドメイン層にアプリケーションロジックが入り込まないようにし、 他のアプリケーションから再利用できる状態を保つ。 サービスレイヤ自体は、各アプリケーションに共通する操作を提 供する。

  16. サービスレイヤを導入する際の注意点 • ここにドメインロジックを入れてしまうと本末転倒。 • 層がひとつ増えるぶんメンテナンスや実行のオーバーヘッドが 増す。

  17. ドメインサービス

  18. ドメインサービス

  19. どのオブジェクトにも属さない操作 “ドメインにおける重要なプロセスや変換処理が、エンティティ や値オブジェクトの自然な責務ではない場合、その操作は、 サービスとして宣言される独立したインターフェースとしてモデ ルに追加すること。モデルの言語を用いてインターフェースを 定義し、操作名が必ずユビキタス言語の一部になるようにす ること。サービスには状態を持たせないこと。” Domain-Driven Design “サービス

    (SERVICES)”
  20. ドメインサービス 例えば、2つの口座間の振込という操作を、振込元と振込先どちら か一方のメソッドとして定義するのではなく、振込という操作を表 現するサービスとして定義した方が自然な場合。

  21. 例: 銀行振込はどこの操作か? どのオブジェクトに追加すべき? raise unless sender_account.balance >= money sender_account.decrease money

    receiver_account.increase money ...
  22. 設計の歪みを避ける どのオブジェクトにも自然に追加できない場合、例えばモデルを入 出力する Command オブジェクトとして追加できる。 BankTransfer.new( money, sender_account, receiver_account ).execute

  23. ドメインサービスの注意点 • あくまでドメイン層にあるオブジェクト。 • その操作が自然に落ち着くオブジェクトがあるならそこに定義 すればいい (わざわざサービスを作る必要ない)。 • やみくもなサービスの追加は、ドメインモデルから必要な振る 舞いをも奪うドメインモデル貧血症をまねく

    (http://bliki-ja.github.io/AnemicDomainModel/)。
  24. まとめ

  25. サービスはいろいろ

  26. TL;DR • サービスには色々ある。 • PofEAA のサービスレイヤと DDD 本のサービスは別物。 • サービスレイヤはドメインロジックとアプリケーションロジックが

    混ざらないようにするための層。 • ドメインサービスは既存のオブジェクトに属せない操作をサー ビスというかたちでドメイン層に定義したもの。 • 導入にはトレードオフがある。