Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

TIL

Slide 4

Slide 4 text

モチベーション Martin Fowler の PofEAA や Eric Evans の Domain-Driven Design に登場する “サービス” と呼ばれるものたちについて整理 し、然るべきタイミングで活用したい。ある日突然 XXService にエ ンカウントしたときに向き合えるようにしておきたい。

Slide 5

Slide 5 text

TL;DR ● サービスには色々ある。 ● PofEAA のサービスレイヤと DDD 本のサービスは別物。 ● サービスレイヤはドメインロジックとアプリケーションロジックが 混ざらないようにするための層。 ● ドメインサービスは既存のオブジェクトに属せない操作をサー ビスというかたちでドメイン層に定義したもの。 ● 導入にはトレードオフがある。

Slide 6

Slide 6 text

サービスはどこにあるか

Slide 7

Slide 7 text

サービスはどこにあるか

Slide 8

Slide 8 text

どこにでもある

Slide 9

Slide 9 text

文脈による

Slide 10

Slide 10 text

サービスはどこにでもある “サービス” はどこにでもあって、文脈によって違う。 ● 振込処理を行う (ドメイン層) ● メールなどで通知する (インフラストラクチャ層) ● 帳票をCSVでエクスポート (アプリケーション層) ● サービスレイヤ (ドメイン層の上にある薄い層)

Slide 11

Slide 11 text

サービスレイヤ

Slide 12

Slide 12 text

サービスレイヤ

Slide 13

Slide 13 text

ドメインロジックを守るレイヤ “... 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”

Slide 14

Slide 14 text

“ビジネスロジック” の内訳 ● ドメインロジック: 純粋にドメインの問題を解決する。 ● アプリケーションロジック:メール通知のような、ドメインロジック ではないアプリケーション固有のロジック。

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

ドメインサービス

Slide 18

Slide 18 text

ドメインサービス

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

まとめ

Slide 25

Slide 25 text

サービスはいろいろ

Slide 26

Slide 26 text

TL;DR ● サービスには色々ある。 ● PofEAA のサービスレイヤと DDD 本のサービスは別物。 ● サービスレイヤはドメインロジックとアプリケーションロジックが 混ざらないようにするための層。 ● ドメインサービスは既存のオブジェクトに属せない操作をサー ビスというかたちでドメイン層に定義したもの。 ● 導入にはトレードオフがある。