Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
ドメイン駆動設計とScala
〜既存プロジェクトへの適用〜
Fumiyasu Sumiya
対象・目的
既存プロジェクトにDDDを適用させてカオスからの脱却
と、Scalaの紹介
アジェンダ
1. 自己紹介
2. HRMOS紹介
3. 本編
4. 締め
3
アジェンダ
1. 自己紹介
2. HRMOS紹介
3. 本編
4. 締め
4
自己紹介
5
角谷 文康(すみや ふみやす)@FScoward
■ 略歴
2011年4月 ~ 2015年7月
TIS株式会社にてクレジットカードシステムの保守開発・新規開発などに従事
- 2014年2月 デブサミ2014登壇
2015年8月
株...
アジェンダ
1. 自己紹介
2. HRMOS紹介
3. 本編
4. 締め
6
7
https://www.hrmos.co/
HRMOS紹介
アジェンダ
1. 自己紹介
2. HRMOS紹介
3. 本編
4. 締め
8
2016年1月~HRMOS採用管理に参画
この時点でかなり、モノとして形になっていた
スピード重視の開発
HRMOSへの参画
9
ドメイン駆動設計は取り入れていなかった
機能追加しようとするとかなり作りが 複雑になっている部分があって、精神的に 辛い
部分があった
今後どんどんと機能追加して使いやすくしていかなければならない
HRMOS採用管理システム
10
今後もどんどん機能追加を行っていく必要があるので、なんとかして 複雑性に立ち向
かわなければならない
HRMOS採用管理システム(課題)
11
今後のためにも
最低限整備しておかないとまずい
実装の複雑性をどうしようか
複雑性に立ち向かう
HRMOS採用管理シ
ステム
(課題)
DDD!!!
18
複雑性はどこから?
19
多くのアプリケーションにおいて、最も重要な複雑さは、技術的なものではない。 複雑
なのはドメインそのもの、すなわち、ユーザの活動やビジネス なのである。ドメインの
持つこの複雑さが設計で扱われないのであれば、基盤となる...
20
設計の時点でスパゲッティコードは運命づけられている
Why DDD?
21
ドメイン意識
なんちゃらServiceにビジネスロジックをまとめ、ごちゃごちゃして複雑になり、
肥大化していってしまうのを防ぐことが出来る
常にドメインモデルを意識した設計を行うので、行き過ぎた単純化・汎用化を
防ぐこと...
Why DDD?
機能実現のためのコード(ソフトウェアの関心事)とビジネスロジック(ドメインの
関心事)は綺麗に分離されていないと、機能追加やバグ修正の時に非常につ
らい思いをする。
22
設計思想の統一
思想がないと実装者、レビュワーによって...
Why DDD?(精神面)
■ 「ソフトウェアの核心にある複雑性に立ち向かう」 ← かっこいい
■ SIerに居た頃は業務がどうなってようが、知ったこっちゃない。言われたと
おりに動くものが作れればOKという感じだったが、それが嫌になって事業
...
Scalaでドメイン駆動設計?
24
■ Scalaは静的型付け言語なのでドメイン駆動設計と相性がいい(と個人的に
は思っている)
■ ちなみにEric Evans本人はRubyが相性が良いかもねと言っている。
● https://www.in...
■ 巨大なモデルが存在(一つのclassでデータ持ちすぎ)
● 大きすぎる集約
■ どのモデルが一体何のためのモデルなのかが明確になっていない
● フロントエンドから受ける/返すためのモデル
● ドメインモデル
● 日付を表すようなYearMo...
モデルとの戦い
26
■ 例えばApplicationと名のつくクラスがいっぱい
モデルとの戦い
27
■ ApplicationInfoという巨大モデル
■ 応募者を表すモデル
■ なぜか求人情報を持っている
■ なぜか面接情報を持っている
■ しかもこの面接情報のなかには面接評価もある
■ これが内部で使いまわされている...
HRMOSの問題
28
1. モデルの定義がぐちゃぐちゃ
2. 大きすぎる集約
3. ドメインモデル貧血症
モデルの再定義
29
まずはユビキタス言語が適切に定義されているかを今一度確認しておく
1. ユビキタス言語
Domain Driven Design
ユビキタス言語とは
31
業務領域についてよく知った人との会話においても お互いに齟齬なく情報を伝え合う
ために用いることが出来る言葉を定義したもの。
システム開発においては、情報伝達の齟齬が発生しておかしなシステムをつくり上げ
ることがままあ...
ユビキタス言語の作成
32
まずはドメインエキスパートとじっくりと会話をしてお互いのことばが滑らかに立ち止ま
ることなく進むようにお互いの ことばによる理解の齟齬をなくすことを目的として作成
する。
世間一般で通じる言葉を用いる必要はなく、 境...
ユビキタス言語の作成
33
ドメインエキスパートは専門的な用語を用いて語りがちだが、それが本当に求めてい
るものを表しているとは限らない
そういった齟齬をなるべく減らすために自分たちで 言葉を再定義する必要がある
チーム全員がその言葉を聞いて勘...
2. 境界づけられたコンテキスト
Domain Driven Design
境界づけられたコンテキスト
35
コンテキストとは、Wikipediaを見ると以下のように定義されています。
>言語学におけるコンテクストとは、メッセージ(例えば1つの文)の意味、メッセージとメッセージの関係、言語が発せられた場所や時代の社会環...
境界づけられたコンテキスト
36
対象とする範囲が異なればドメインモデルは意味をなさなくなるということがわかる。
なので、初めに自分たちの定めようとするドメインモデルがどのコンテキストに属する
ものなのかをきちんと定義する必要がある。
ドメインを見つけ出し、境界づける
37
自分たちの行う事業の ドメインは一体何なのか
採用管理、勤怠管理、評価管理...etc
それぞれ明確な境界があり、採用管理コンテキスト、勤怠管理コンテキストと言った、
各コンテキストを境界づけることが出来...
コンテキストマップ
38
コンテキストマップと呼ばれる図を描くことで、それぞれのドメインが担うべき役割を明
確に分けることができて、ドメインモデルがどこに属するかを端的に表すことが出来る
※「境界づける」というのはドメインモデルに明確に区別をつ...
コンテキストマップ
39
モデルが適用されるコンテキストを明示的に定義すること。明示的な境界は、チーム
編成、そのアプリケーションに特有の部分が持つ用途、コードベースやデータベース
スキーマなどの物理的な表現などの観点から設定 すること。その境...
境界づけられたコンテキスト 超意訳
ことばの定義、意味が変わらない範囲を定めること
きつね?たぬき?
41
■ 関東のたぬきそば
■ 大阪の立ち食いそば屋のたぬきそば
きつね?たぬき?
42
Wikipediaより
https://ja.wikipedia.org/wiki/%E3%81%9F%E3%81%AC%E3%81%8D_(%E9%BA%BA%E9%A1
%9E)
関東 関西
きつね 油揚げをのせたそ...
きつね?たぬき?(ポルナレフ状態)
43
あ…ありのまま 今 起こった事を話すぜ!
「おれは 大阪の立ち食い蕎麦屋でたぬきそばを頼んだら
なぜか上に油揚げがのっていた」
な… 何を言っているのか わからねーと思うが 
おれも 何をされたのか わ...
HRMOSの問題
44
1. モデルの定義がぐちゃぐちゃ
2. 大きすぎる集約
3. ドメインモデル貧血症
なぜモデルの定義がぐちゃぐちゃになってしまうのか
モデルの定義がぐちゃぐちゃ
45
■ Applicationと名のつくクラスがいっぱい
モデルの定義がぐちゃぐちゃ
46
■ ApplicationInfoという巨大モデル
■ 応募者を表すモデル
■ なぜか求人情報を持っている
■ なぜか面接情報を持っている
■ しかもこの面接情報のなかには面接評価もある
■ これが内部で使いま...
モデルを明確に分けていない
47
リクエストを受け付けたときのモデルなのか、ドメインモデルなのか、レスポンス用の
モデルなのかがわけられておらず、無法地帯になってしまっている。
そこで、パッケージによる手助けをして解決を目指す。
パッケージ分けによるサポート
48
■ controller - コントローラー層 Inputの変換を行う
● model - データを受けとるためのモデル
■ presenter - プレゼンター層 Outputへの変換を行う
● model...
引用 - http://qiita.com/kondei/items/41c28674c1bfd4156186
3. ドメインモデルを見つけ出す
Domain Driven Design
ドメインモデルを見つけ出す
51
ユビキタス言語が作れたらあとは見つけ出した ことばたちをドメインモデルとして落と
し込むだけ
ドメインモデルに落とし込む
52
1. エンティティ(Entity)
2. バリューオブジェクト(ValueObject)
3. 集約(Aggregate)
これら3つの概念を押さえておく必要がある
ドメインモデルに落とし込む
53
1. エンティティ(Entity)
2. バリューオブジェクト(ValueObject)
3. 集約(Aggregate)
Entityとは
Entity
54
■ Entityは(同一性を)識別することが必要となるモデルのこと
● 簡単に言うと他と区別するためのIDを持たせて管理するということ
■ 同一性を担保出来れば識別子はなんでも良い
55
Entity
田中太郎くん(10歳)と6年後の田中太郎くん(16歳)は同一人物
年齢などの属性が異なるだけ
田中太郎くん(10)
田中太郎くん(16)
56
同一性を担保する識別子は何か
名前?年齢?性別?
名前+年齢?名前+年齢+性別?
田中太郎くん(10) 田中太郎くん(16) 里中太郎くん(27)
57
同一性を担保する識別子は何か
識別子は国民総背番号「行政手続における特定の個人を識別するための番号の利
用等に関する法律」で定められたマイナンバー
ドメインモデルに落とし込む
58
1. エンティティ(Entity)
2. バリューオブジェクト(ValueObject)
3. 集約(Aggregate)
バリューオブジェクトとは
ValueObject
59
■ イミュータブルに保つ(状態を管理しない)値
■ 状態を持たないオブジェクトとすることで、複雑性の排除に役立つ
Scala講座
■ Scalaでは値は基本的にval(イミュータブル)で宣言するのでValueObjectで
あることを担保しやすくなっている
● ※ var(ミュータブル)で宣言も可能
■ case classもイミュータブル
60
Scala講座 〜 case class について 〜
61
Scalaでは case class というものがつくれて宣言が簡単になる
ValueObject 例え話
62
■ 誕生日をどう表すか
■ 単純にDate型で表すのかBirthDate型を作るか
■ Dateでやると年齢を別の場所で算出しなければならない
● HRMOS採用管理ではUtilでやっていた
■ Birth...
BirthDateというValueObject
Entity / ValueObject 例え話
64
■ 同姓同名の人がいたとしてもそれは別人なので、”人”としてはきちんと識
別する必要がある
● case class Human (id: ID, name: Name, gender: ...
65
Entity / ValueObject 例え話
国民を番号で管理するに当たって名前などを仔細に管理する必要はない
性別も名前も年齢もただの記号でしかないとすれば、 ValueObjectで良い
田中太郎くん(10)
田中太郎くん(16)
主体によってEntityとValueObjectは変化する
66
たとえばお札(千円札)
一般人にとっては千円のお札は千円でしかない(千円であると認識していれば良い)
ので、ValueObject
日本銀行からすればお札一枚一枚についてキチンと...
一般人にとっての千円
日本銀行にとっての千円 http://www.npb.go.jp/ja/intro/kihon/genzai.html
日本銀行にとっての千円
ドメインモデルに落とし込む
70
1. エンティティ(Entity)
2. バリューオブジェクト(ValueObject)
3. 集約(Aggregate)
集約とは?
集約(Aggregate)
71
■ エンティティのライフサイクルを同一にするものを集める集約は最小限に
■ keyword:
● トランザクション整合性
● 結果整合性
エンティティのライフサイクル
72
エンティティと値オブジェクトを 集約の中にまとめ、各集約の周囲に境界を定義するこ
と。各集約に対してルートとなるエンティティを1つ選び、境界の内部に存在するオブ
ジェクトへのアクセスは、その ルートを経由して...
集約
73
トランザクション整合性を保つ必要のあるエンティティたちを1つに 集約する。
集約の境界の外部は結果整合性を用いる。
E.g. 自動車(Entity)はタイヤ(Entity)、車輌(Entity)で構成される。
タイヤと車輌は自動車を...
集約のルール
74
集約内部のオブジェクトに対してアクセスしてよいのは集約の ルートのみ。
内部を変更したい場合には 必ず集約のルートを通して変更を行う こと。
集約のルール(例)
75
車の速度を上げるのに、タイヤに対して速度を上げるように命令を出すのではなく、車
に対して速度を上げるように命令して、車がタイヤ(エンジン)の回転数を上げるように
する
集約は非常に難しい
76
■ オブジェクトのライフサイクルに対する今までの考え方を捨てて集約につい
て向き合わなければならない
■ トランザクション整合性?結果整合性?
■ 全部含んで巨大な集約できちゃうよ・・・
集約はなぜ難しいのか
77
■ ビジネス的なライフサイクル?
■ システム的なライフサイクル?
■ 頭のなかで概念が交錯する
たとえば
78
自動車は車両、タイヤで構成されているが、エンジンも構成物のひとつ
ビジネス(ドメイン)の関心事として エンジンは生成から破棄までをキチンと管理したい
とすると、エンジンは自動車の集約の内部にあるべきだろうか?
自動車の生成〜破棄...
たとえば
79
たとえば、面接と面接評価を考えてみる。
「面接」設定時点では「面接評価」自体は空なので ライフサイクルが違うように思える
が、「面接評価」はそもそも「面接」がないと存在し得ないので「面接」と「面接評価」は
同一の集約であり、「面...
たとえばこうなる
集約の勝手な解釈
81
■ 一つの集約のルート(エンティティ)でどこまで責任を持つかということ
■ モデルの一貫性を保つためのものが集約である
■ (参考)http://masuda220.jugem.jp?day=20091126
ドメインモデル図を描いてみる
ユビキタス言語を定義し、ドメインモデルとしてEntity、ValueObject、集約につ
いて理解したらドメインモデル図を描いてチーム全員での認識が正しくなされ
ているかを確認する
PlantUmlでドメインモデル図を書く
HRMOSの問題
84
1. モデルの定義がぐちゃぐちゃ
2. 大きすぎる集約
3. ドメインモデル貧血症
集約が大きすぎる
■ 応募者の情報であれば求人情報はいらない
し、面接の情報もいらない
■ レジュメの情報も集約としては別として小さ
な集約を目指す。
85
パフォーマンス問題
86
■ SQLTimeoutが頻発するようになっていた(DDD取り入れる前から)
■ 1つのSQLで大量にデータ取りすぎている
■ この問題はDDDでは解決できず、逆にすべてにドメインモデルを強制する
とパフォーマンスは劣...
CQRS(コマンドクエリ責務分離)という考え方
87
■ DBからデータ引っ張ってちょっとしたデータ表示したいという要求に対して
もドメインモデルを用いるべきか?
■ コマンドとクエリに分け、クエリの場合にはドメインモデルをスキップしても
良い...
Command
88
フロントエンドから問い合わせがあってビジネスロジックを用いるのであればコマンドと
してドメインモデルを活かして 実装をする。
Query
89
フロントエンドから問い合わせがあってデータを返すだけで良いのであれば クエリなの
でドメインモデルはスキップして、欲しいデータだけを素早く取るように実装する
ドメインモデルとリポジトリの関係
個人的にはドメインモデルに永続化は持たせたくない
HRMOSの問題
94
1. モデルの定義がぐちゃぐちゃ
2. 大きすぎる集約
3. ドメインモデル貧血症
DDDでよく語られるドメインモデル貧血症
95
■ ドメインモデルっぽく出来たものの実際はただのデータを入れる箱でしか無
くドメインモデルがどういった責務を果たすべきなのかが明確になっていな
い(外部に出てしまっている)状態
■ サービス層にば...
DDDでよく語られるドメインモデル貧血症
96
■ HRMOSではScalaを使っているのでgetter, setterは無いがメソッドを持たな
いcase class が大量に存在
■ また、XXServiceやXXUtilといったクラスがあ...
DDDを超意訳すると
DDDはドメインモデルを用いて、ソフトウェアの関心事とドメインの関心事をキ
チンと分けて設計しましょうというお話
98
DDDを理解して実践できているような口ぶりで説明をしてきましたが
まだまだ道半ば
99
DDDを理解して実践できているような口ぶりで説明をしてきましたが
まだまだ道半ば
We are hiring!
■ Bizreach: https://bizreach.biz/landing/base_01
■ HRMOS: https://www.hrmos.co/saiyo/
■ Stanby: https://jp....
【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜
【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜
【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜
【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜
Upcoming SlideShare
Loading in …5
×

【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜

1,387 views

Published on

JJUG CCC 2016 Fall にて発表した資料です。

Published in: Technology
  • Be the first to comment

【JJUG CCC 2016 Fall 公開版】ドメイン駆動設計とscala 〜既存プロジェクトへの適用〜

  1. 1. ドメイン駆動設計とScala 〜既存プロジェクトへの適用〜 Fumiyasu Sumiya
  2. 2. 対象・目的 既存プロジェクトにDDDを適用させてカオスからの脱却 と、Scalaの紹介
  3. 3. アジェンダ 1. 自己紹介 2. HRMOS紹介 3. 本編 4. 締め 3
  4. 4. アジェンダ 1. 自己紹介 2. HRMOS紹介 3. 本編 4. 締め 4
  5. 5. 自己紹介 5 角谷 文康(すみや ふみやす)@FScoward ■ 略歴 2011年4月 ~ 2015年7月 TIS株式会社にてクレジットカードシステムの保守開発・新規開発などに従事 - 2014年2月 デブサミ2014登壇 2015年8月 株式会社ビズリーチ入社 2015年8月 ~ 2015年12月 スタンバイ のサーバーサイドエンジニア 2016年1月 ~ 現在 HRMOS採用管理 のサーバーサイドエンジニア 2016年12月3日 JJUG CCC ■ 好きなもの スフィア、乃木坂46、欅坂46
  6. 6. アジェンダ 1. 自己紹介 2. HRMOS紹介 3. 本編 4. 締め 6
  7. 7. 7 https://www.hrmos.co/ HRMOS紹介
  8. 8. アジェンダ 1. 自己紹介 2. HRMOS紹介 3. 本編 4. 締め 8
  9. 9. 2016年1月~HRMOS採用管理に参画 この時点でかなり、モノとして形になっていた スピード重視の開発 HRMOSへの参画 9
  10. 10. ドメイン駆動設計は取り入れていなかった 機能追加しようとするとかなり作りが 複雑になっている部分があって、精神的に 辛い 部分があった 今後どんどんと機能追加して使いやすくしていかなければならない HRMOS採用管理システム 10
  11. 11. 今後もどんどん機能追加を行っていく必要があるので、なんとかして 複雑性に立ち向 かわなければならない HRMOS採用管理システム(課題) 11
  12. 12. 今後のためにも 最低限整備しておかないとまずい
  13. 13. 実装の複雑性をどうしようか
  14. 14. 複雑性に立ち向かう
  15. 15. HRMOS採用管理シ ステム (課題)
  16. 16. DDD!!! 18
  17. 17. 複雑性はどこから? 19 多くのアプリケーションにおいて、最も重要な複雑さは、技術的なものではない。 複雑 なのはドメインそのもの、すなわち、ユーザの活動やビジネス なのである。ドメインの 持つこの複雑さが設計で扱われないのであれば、基盤となる技術が適切に考えられ ていたとしても意味がない。設計を成功させるためには、ソフトウェアにおけるこの中 心的な側面を、体系的に扱わなければならない。 エリック・エヴァンスのドメイン駆動設計 まえがき 複雑さという課題
  18. 18. 20 設計の時点でスパゲッティコードは運命づけられている
  19. 19. Why DDD? 21 ドメイン意識 なんちゃらServiceにビジネスロジックをまとめ、ごちゃごちゃして複雑になり、 肥大化していってしまうのを防ぐことが出来る 常にドメインモデルを意識した設計を行うので、行き過ぎた単純化・汎用化を 防ぐことが出来る 複雑性に立ち向かう 責務を明確に ドメインモデルに正しく処理をもたせるため、誰が何をするのかが明確になる (処理が各所に散らばらない)
  20. 20. Why DDD? 機能実現のためのコード(ソフトウェアの関心事)とビジネスロジック(ドメインの 関心事)は綺麗に分離されていないと、機能追加やバグ修正の時に非常につ らい思いをする。 22 設計思想の統一 思想がないと実装者、レビュワーによってコードの実装に偏りが生じる ※ 毎回全員がレビューしてるなら別 ビジネスロジックへの 集中 ScalaとDDDは相性が いいらしい 某社はDDDをやりやすくするためにScalaを使ったらしい
  21. 21. Why DDD?(精神面) ■ 「ソフトウェアの核心にある複雑性に立ち向かう」 ← かっこいい ■ SIerに居た頃は業務がどうなってようが、知ったこっちゃない。言われたと おりに動くものが作れればOKという感じだったが、それが嫌になって事業 会社に転職したので、きちんと業務を理解して、あるべき姿のきれいなシス テム作りをしたかった ■ 我々”一般的な”技術者が解決しなければならないのは技術的問題の前 に、ビジネスの問題であるということを認識しなければならない。 23
  22. 22. Scalaでドメイン駆動設計? 24 ■ Scalaは静的型付け言語なのでドメイン駆動設計と相性がいい(と個人的に は思っている) ■ ちなみにEric Evans本人はRubyが相性が良いかもねと言っている。 ● https://www.infoq.com/jp/articles/eric-evans-ddd-matters-today ● 理由としてはrubyがドメイン固有言語(DomainSpecificLanguage)を簡単に作成できる点にあ る。 ● ドメイン駆動での開発はDSLでメタプログラミングでシステムを作ることなのかもしれない。 ● DSLについて語るつもりはない(というか語れるほど詳しくない)ので、各自調べてみてくださ い。 ● http://www.slideshare.net/yizawa/rubydsl-25541986
  23. 23. ■ 巨大なモデルが存在(一つのclassでデータ持ちすぎ) ● 大きすぎる集約 ■ どのモデルが一体何のためのモデルなのかが明確になっていない ● フロントエンドから受ける/返すためのモデル ● ドメインモデル ● 日付を表すようなYearMonthDateというクラスなどもあったがドメインモデルではない ■ ドメインモデル貧血症に陥っている ● モデルはメソッドをほぼ持っていない ● XXService, XXUtil にビジネスロジックが散らばっている ● ソフトウェアの関心事とビジネスの関心事の分離が出来ていないため処理が複雑に HRMOS採用管理での問題点 25
  24. 24. モデルとの戦い 26 ■ 例えばApplicationと名のつくクラスがいっぱい
  25. 25. モデルとの戦い 27 ■ ApplicationInfoという巨大モデル ■ 応募者を表すモデル ■ なぜか求人情報を持っている ■ なぜか面接情報を持っている ■ しかもこの面接情報のなかには面接評価もある ■ これが内部で使いまわされている ■ しかもこいつはメソッドを持っていない ■ このクラスでフロントエンドへ返している
  26. 26. HRMOSの問題 28 1. モデルの定義がぐちゃぐちゃ 2. 大きすぎる集約 3. ドメインモデル貧血症
  27. 27. モデルの再定義 29 まずはユビキタス言語が適切に定義されているかを今一度確認しておく
  28. 28. 1. ユビキタス言語 Domain Driven Design
  29. 29. ユビキタス言語とは 31 業務領域についてよく知った人との会話においても お互いに齟齬なく情報を伝え合う ために用いることが出来る言葉を定義したもの。 システム開発においては、情報伝達の齟齬が発生しておかしなシステムをつくり上げ ることがままあるが、こういった齟齬をなくすためのプロダクトに関わる全員とスムーズ に会話を行うための言語のことを作り上げることをやっておく必要がある。
  30. 30. ユビキタス言語の作成 32 まずはドメインエキスパートとじっくりと会話をしてお互いのことばが滑らかに立ち止ま ることなく進むようにお互いの ことばによる理解の齟齬をなくすことを目的として作成 する。 世間一般で通じる言葉を用いる必要はなく、 境界づけられたコンテキスト 内で通じる言 葉が出来ればいい ※ ドメインエキスパート とは、業務領域についての深い知識を持っている人物のこと であって必ずしも役職者ではない。
  31. 31. ユビキタス言語の作成 33 ドメインエキスパートは専門的な用語を用いて語りがちだが、それが本当に求めてい るものを表しているとは限らない そういった齟齬をなるべく減らすために自分たちで 言葉を再定義する必要がある チーム全員がその言葉を聞いて勘違いすることなく、同じ物事を思い浮かべることが 出来るまで言葉を洗練するのが重要
  32. 32. 2. 境界づけられたコンテキスト Domain Driven Design
  33. 33. 境界づけられたコンテキスト 35 コンテキストとは、Wikipediaを見ると以下のように定義されています。 >言語学におけるコンテクストとは、メッセージ(例えば1つの文)の意味、メッセージとメッセージの関係、言語が発せられた場所や時代の社会環境、 言語伝達に関連するあらゆる知覚を意味し、コミュニケーションの場で使用される言葉や表現を定義付ける背景や状況そのものを指す。 例えば日本 語で会話をする2者が「ママ」について話をしている時に、その2者の立場、関係性、前後の会話によって「ママ」の意味は異なる。2人が兄弟なのであ れば自分達の母親についての話であろうし、クラブホステス同士の会話であれば店の女主人のことを指すであろう 。このように相対的に定義が異な る言葉の場合は、コミュニケーションをとる2者の間でその関係性、背景や状況に対する認識が共有・同意されていなければ会話が成立しない。この ような、コミュニケーションを成立させる共有情報をコンテクスト という。 >マーケティングの方法論として、顧客の背景を理解・把握したうえで、それに沿った商品プロモーションを行うことを「コンテクスト・マーケティング」と 呼ぶ。 >情報工学におけるコンテキストは、デバイスが使われている状況を意味する。例えばある時点でデバイスを使用しているユーザーなど。コンテキス トアウェアネスおよびコンテキストスイッチを参照されたい。 >人工知能におけるコンテキストは、意思伝達、言語学、形而上学などに属する部分と深い関係がある。自動的な推論を使ってそれらの観点が如何 にしてコンピュータシステム上でモデル化できるかは、人工知能の研究テーマの1つである。 >シチュエーション・コメディにおけるコンテクストとは、そのショーが公開されている時代背景やその時点の社会の出来事などを意味する。例えば、"I love Lucy"には1950年代のアメリカのコンテクストが反映されている。 >心理学におけるコンテクストとは、フォアグラウンドの事象に伴うバックグラウンドの刺激を意味する。例えば、ネズミがネコを恐れながらエサを探し ているとき、ネコがフォアグラウンドの事象であり、探し回っている場所(および時間)がバックグラウンドの刺激である。海馬にはある種のコンテクスト 処理に特化した神経構造があると考えられている。
  34. 34. 境界づけられたコンテキスト 36 対象とする範囲が異なればドメインモデルは意味をなさなくなるということがわかる。 なので、初めに自分たちの定めようとするドメインモデルがどのコンテキストに属する ものなのかをきちんと定義する必要がある。
  35. 35. ドメインを見つけ出し、境界づける 37 自分たちの行う事業の ドメインは一体何なのか 採用管理、勤怠管理、評価管理...etc それぞれ明確な境界があり、採用管理コンテキスト、勤怠管理コンテキストと言った、 各コンテキストを境界づけることが出来る。
  36. 36. コンテキストマップ 38 コンテキストマップと呼ばれる図を描くことで、それぞれのドメインが担うべき役割を明 確に分けることができて、ドメインモデルがどこに属するかを端的に表すことが出来る ※「境界づける」というのはドメインモデルに明確に区別をつけてドメインモデルを 共有 しないということ
  37. 37. コンテキストマップ 39 モデルが適用されるコンテキストを明示的に定義すること。明示的な境界は、チーム 編成、そのアプリケーションに特有の部分が持つ用途、コードベースやデータベース スキーマなどの物理的な表現などの観点から設定 すること。その境界内では、モデル を厳密に一貫性のあるものに保つこと。ただし、境界の外部の問題によって注意を逸 らされたり、混乱させられたりするのを避けること。 エリック・エヴァンスのドメイン駆動設計 第14章 モデルの整合性を維持する p.344
  38. 38. 境界づけられたコンテキスト 超意訳 ことばの定義、意味が変わらない範囲を定めること
  39. 39. きつね?たぬき? 41 ■ 関東のたぬきそば ■ 大阪の立ち食いそば屋のたぬきそば
  40. 40. きつね?たぬき? 42 Wikipediaより https://ja.wikipedia.org/wiki/%E3%81%9F%E3%81%AC%E3%81%8D_(%E9%BA%BA%E9%A1 %9E) 関東 関西 きつね 油揚げをのせたそば又はうど ん (きつねうどん、きつねそば) 油揚げの甘煮をのせたうどん (けつね、しのだ) たぬき 揚げ玉をのせたそば又はうど ん (たぬきうどん、たぬきそば) 京都:刻んだ油揚げ[21]と青 ねぎをあんかけにしたうどん 又はそば 大阪:油揚げの甘煮またはキ ザミをのせたそば
  41. 41. きつね?たぬき?(ポルナレフ状態) 43 あ…ありのまま 今 起こった事を話すぜ! 「おれは 大阪の立ち食い蕎麦屋でたぬきそばを頼んだら なぜか上に油揚げがのっていた」 な… 何を言っているのか わからねーと思うが  おれも 何をされたのか わからなかった… 頭がどうにかなりそうだった… 催眠術だとか超スピードだと か そんなチャチなもんじゃあ 断じてねえ もっと恐ろしいものの片鱗を 味わったぜ…
  42. 42. HRMOSの問題 44 1. モデルの定義がぐちゃぐちゃ 2. 大きすぎる集約 3. ドメインモデル貧血症 なぜモデルの定義がぐちゃぐちゃになってしまうのか
  43. 43. モデルの定義がぐちゃぐちゃ 45 ■ Applicationと名のつくクラスがいっぱい
  44. 44. モデルの定義がぐちゃぐちゃ 46 ■ ApplicationInfoという巨大モデル ■ 応募者を表すモデル ■ なぜか求人情報を持っている ■ なぜか面接情報を持っている ■ しかもこの面接情報のなかには面接評価もある ■ これが内部で使いまわされている ■ しかもこいつはメソッドを持っていない ■ このクラスでフロントエンドへ返している
  45. 45. モデルを明確に分けていない 47 リクエストを受け付けたときのモデルなのか、ドメインモデルなのか、レスポンス用の モデルなのかがわけられておらず、無法地帯になってしまっている。 そこで、パッケージによる手助けをして解決を目指す。
  46. 46. パッケージ分けによるサポート 48 ■ controller - コントローラー層 Inputの変換を行う ● model - データを受けとるためのモデル ■ presenter - プレゼンター層 Outputへの変換を行う ● model - データを返すためのモデル ■ application - アプリケーション層 ● service - 調整役。処理の振り分けを行う。 トランザクション制御 もここ。ドメインロジックは存在しては ならない。 ■ domain - ドメイン層 ● model - ドメインモデル。packageで集約をまとめる。ドメインロジックを記 ● service - エンティティや値オブジェクトで行うには 不自然なビジネスロジックを記述 ■ infrastructure - インフラ層 ● repository - 永続化についての責務を負う ■ gateway - ゲートウェイ層。 外部サービスとのやり取りを行う。外部のメールサービスとか ■ util - ユーティリティ
  47. 47. 引用 - http://qiita.com/kondei/items/41c28674c1bfd4156186
  48. 48. 3. ドメインモデルを見つけ出す Domain Driven Design
  49. 49. ドメインモデルを見つけ出す 51 ユビキタス言語が作れたらあとは見つけ出した ことばたちをドメインモデルとして落と し込むだけ
  50. 50. ドメインモデルに落とし込む 52 1. エンティティ(Entity) 2. バリューオブジェクト(ValueObject) 3. 集約(Aggregate) これら3つの概念を押さえておく必要がある
  51. 51. ドメインモデルに落とし込む 53 1. エンティティ(Entity) 2. バリューオブジェクト(ValueObject) 3. 集約(Aggregate) Entityとは
  52. 52. Entity 54 ■ Entityは(同一性を)識別することが必要となるモデルのこと ● 簡単に言うと他と区別するためのIDを持たせて管理するということ ■ 同一性を担保出来れば識別子はなんでも良い
  53. 53. 55 Entity 田中太郎くん(10歳)と6年後の田中太郎くん(16歳)は同一人物 年齢などの属性が異なるだけ 田中太郎くん(10) 田中太郎くん(16)
  54. 54. 56 同一性を担保する識別子は何か 名前?年齢?性別? 名前+年齢?名前+年齢+性別? 田中太郎くん(10) 田中太郎くん(16) 里中太郎くん(27)
  55. 55. 57 同一性を担保する識別子は何か 識別子は国民総背番号「行政手続における特定の個人を識別するための番号の利 用等に関する法律」で定められたマイナンバー
  56. 56. ドメインモデルに落とし込む 58 1. エンティティ(Entity) 2. バリューオブジェクト(ValueObject) 3. 集約(Aggregate) バリューオブジェクトとは
  57. 57. ValueObject 59 ■ イミュータブルに保つ(状態を管理しない)値 ■ 状態を持たないオブジェクトとすることで、複雑性の排除に役立つ
  58. 58. Scala講座 ■ Scalaでは値は基本的にval(イミュータブル)で宣言するのでValueObjectで あることを担保しやすくなっている ● ※ var(ミュータブル)で宣言も可能 ■ case classもイミュータブル 60
  59. 59. Scala講座 〜 case class について 〜 61 Scalaでは case class というものがつくれて宣言が簡単になる
  60. 60. ValueObject 例え話 62 ■ 誕生日をどう表すか ■ 単純にDate型で表すのかBirthDate型を作るか ■ Dateでやると年齢を別の場所で算出しなければならない ● HRMOS採用管理ではUtilでやっていた ■ BirthDateを用意してcalcAgeのようなメソッドを用意してやったほうが良い
  61. 61. BirthDateというValueObject
  62. 62. Entity / ValueObject 例え話 64 ■ 同姓同名の人がいたとしてもそれは別人なので、”人”としてはきちんと識 別する必要がある ● case class Human (id: ID, name: Name, gender: Gender) ■ 一方で”名前”というオブジェクトに注目するとただの文字の羅列でしかな いので、識別する必要はなく識別子を持たずにただの置き換え可能な値 (ValueObject)として扱えば良い ● case class Name(firstName: String, lastName: String)
  63. 63. 65 Entity / ValueObject 例え話 国民を番号で管理するに当たって名前などを仔細に管理する必要はない 性別も名前も年齢もただの記号でしかないとすれば、 ValueObjectで良い 田中太郎くん(10) 田中太郎くん(16)
  64. 64. 主体によってEntityとValueObjectは変化する 66 たとえばお札(千円札) 一般人にとっては千円のお札は千円でしかない(千円であると認識していれば良い) ので、ValueObject 日本銀行からすればお札一枚一枚についてキチンと区別して管理する必要があるた め、お札はEntity(識別子は「記番号」)
  65. 65. 一般人にとっての千円
  66. 66. 日本銀行にとっての千円 http://www.npb.go.jp/ja/intro/kihon/genzai.html
  67. 67. 日本銀行にとっての千円
  68. 68. ドメインモデルに落とし込む 70 1. エンティティ(Entity) 2. バリューオブジェクト(ValueObject) 3. 集約(Aggregate) 集約とは?
  69. 69. 集約(Aggregate) 71 ■ エンティティのライフサイクルを同一にするものを集める集約は最小限に ■ keyword: ● トランザクション整合性 ● 結果整合性
  70. 70. エンティティのライフサイクル 72 エンティティと値オブジェクトを 集約の中にまとめ、各集約の周囲に境界を定義するこ と。各集約に対してルートとなるエンティティを1つ選び、境界の内部に存在するオブ ジェクトへのアクセスは、その ルートを経由して制御 すること。外部のオブジェクトが参 照を保持できるのは、ルートのみとすること。内部のメンバに対する一時的な参照を 渡して良いのは、単一の操作で使用する時だけだ。ルートがアクセスを制御するの で、内部が知らないうちに変更されることはなくなる。この取り決めにより、どんな状態 変化においても、集約内にあるオブジェクトと集約全体に対して、不変条件をすべて 強制することが現実的になる。 (エリック・エヴァンスのドメイン駆動設計 p.127 第6章 ドメインオブジェクトのライフサ イクル)
  71. 71. 集約 73 トランザクション整合性を保つ必要のあるエンティティたちを1つに 集約する。 集約の境界の外部は結果整合性を用いる。 E.g. 自動車(Entity)はタイヤ(Entity)、車輌(Entity)で構成される。 タイヤと車輌は自動車を構成するものであり、生成~破棄が同一のタイミングで行わ れるものとすると、自動車(Entity)は 集約のルートエンティティとなる。
  72. 72. 集約のルール 74 集約内部のオブジェクトに対してアクセスしてよいのは集約の ルートのみ。 内部を変更したい場合には 必ず集約のルートを通して変更を行う こと。
  73. 73. 集約のルール(例) 75 車の速度を上げるのに、タイヤに対して速度を上げるように命令を出すのではなく、車 に対して速度を上げるように命令して、車がタイヤ(エンジン)の回転数を上げるように する
  74. 74. 集約は非常に難しい 76 ■ オブジェクトのライフサイクルに対する今までの考え方を捨てて集約につい て向き合わなければならない ■ トランザクション整合性?結果整合性? ■ 全部含んで巨大な集約できちゃうよ・・・
  75. 75. 集約はなぜ難しいのか 77 ■ ビジネス的なライフサイクル? ■ システム的なライフサイクル? ■ 頭のなかで概念が交錯する
  76. 76. たとえば 78 自動車は車両、タイヤで構成されているが、エンジンも構成物のひとつ ビジネス(ドメイン)の関心事として エンジンは生成から破棄までをキチンと管理したい とすると、エンジンは自動車の集約の内部にあるべきだろうか? 自動車の生成〜破棄とエンジンの生成〜破棄は果たして同じ ライフサイクルだろう か?
  77. 77. たとえば 79 たとえば、面接と面接評価を考えてみる。 「面接」設定時点では「面接評価」自体は空なので ライフサイクルが違うように思える が、「面接評価」はそもそも「面接」がないと存在し得ないので「面接」と「面接評価」は 同一の集約であり、「面接」は集約のルートになるかもしれない
  78. 78. たとえばこうなる
  79. 79. 集約の勝手な解釈 81 ■ 一つの集約のルート(エンティティ)でどこまで責任を持つかということ ■ モデルの一貫性を保つためのものが集約である ■ (参考)http://masuda220.jugem.jp?day=20091126
  80. 80. ドメインモデル図を描いてみる ユビキタス言語を定義し、ドメインモデルとしてEntity、ValueObject、集約につ いて理解したらドメインモデル図を描いてチーム全員での認識が正しくなされ ているかを確認する
  81. 81. PlantUmlでドメインモデル図を書く
  82. 82. HRMOSの問題 84 1. モデルの定義がぐちゃぐちゃ 2. 大きすぎる集約 3. ドメインモデル貧血症
  83. 83. 集約が大きすぎる ■ 応募者の情報であれば求人情報はいらない し、面接の情報もいらない ■ レジュメの情報も集約としては別として小さ な集約を目指す。 85
  84. 84. パフォーマンス問題 86 ■ SQLTimeoutが頻発するようになっていた(DDD取り入れる前から) ■ 1つのSQLで大量にデータ取りすぎている ■ この問題はDDDでは解決できず、逆にすべてにドメインモデルを強制する とパフォーマンスは劣化する可能性がある
  85. 85. CQRS(コマンドクエリ責務分離)という考え方 87 ■ DBからデータ引っ張ってちょっとしたデータ表示したいという要求に対して もドメインモデルを用いるべきか? ■ コマンドとクエリに分け、クエリの場合にはドメインモデルをスキップしても 良いのではないか? ■ 全部が全部ドメインモデルを用いていてはパフォーマンスに問題ありそう
  86. 86. Command 88 フロントエンドから問い合わせがあってビジネスロジックを用いるのであればコマンドと してドメインモデルを活かして 実装をする。
  87. 87. Query 89 フロントエンドから問い合わせがあってデータを返すだけで良いのであれば クエリなの でドメインモデルはスキップして、欲しいデータだけを素早く取るように実装する
  88. 88. ドメインモデルとリポジトリの関係
  89. 89. 個人的にはドメインモデルに永続化は持たせたくない
  90. 90. HRMOSの問題 94 1. モデルの定義がぐちゃぐちゃ 2. 大きすぎる集約 3. ドメインモデル貧血症
  91. 91. DDDでよく語られるドメインモデル貧血症 95 ■ ドメインモデルっぽく出来たものの実際はただのデータを入れる箱でしか無 くドメインモデルがどういった責務を果たすべきなのかが明確になっていな い(外部に出てしまっている)状態 ■ サービス層にばかり処理を書いて、ドメインモデルがほとんどgetterと setterばかりになってしまっている状態のこと
  92. 92. DDDでよく語られるドメインモデル貧血症 96 ■ HRMOSではScalaを使っているのでgetter, setterは無いがメソッドを持たな いcase class が大量に存在 ■ また、XXServiceやXXUtilといったクラスがあらゆるロジックを持っていたが それを再定義したドメインモデルのクラスに少しずつ移譲 ■ 少しずつリファクタリングを進めて貧血状態から抜け出せるように
  93. 93. DDDを超意訳すると DDDはドメインモデルを用いて、ソフトウェアの関心事とドメインの関心事をキ チンと分けて設計しましょうというお話
  94. 94. 98 DDDを理解して実践できているような口ぶりで説明をしてきましたが まだまだ道半ば
  95. 95. 99 DDDを理解して実践できているような口ぶりで説明をしてきましたが まだまだ道半ば
  96. 96. We are hiring! ■ Bizreach: https://bizreach.biz/landing/base_01 ■ HRMOS: https://www.hrmos.co/saiyo/ ■ Stanby: https://jp.stanby.com/ ■ Careertrek: https://careertrek.biz/?trcd=corp ■ Bizreach CAMPUS: https://br-campus.jp/ etc...

×