0
某 S 社 の DDD
-どうしてこうなった駆動開発-
@kumake1004
自己紹介
名前@kumake1004
‒ Sansan 株式会社 アプリケーションエンジニア
‒ 2011年入社 (5年目)
仕事
‒ 法人向け名刺管理アプリのサーバーサイド実装
‒ アプリエンジニアとインフラエンジニアの板挟みにあうこと
興味...
どうしてこうなった駆動開発とは
職場で DDD 導入したら失敗しました
‒ (個人の感想です)
再挑戦を始めたところ、、、
‒ 漠然と思いはあって、良い機会なので振り返って言語化します
‒ という普通の失敗事例紹介
つまりただの出オチ
- 実践ドメイン駆動設計 コアドメイン (スクラム) における集約の使用
“彼らには DDD の経験があまりなかった。そのため、チームは DDD に関
してちょっとした間違いを犯した。”
“最終的に彼らは、自分たちが集約を扱った経験を糧にして成...
DDD 導入の背景
名刺管理 Web アプリケーション
‒ C# / ASP.NET / PostgreSQL 他
‒ 生まれて 8 年なので色々つらい(トランザクションスクリプトはやだ!)
‒ もっと早くて質の良いソフトウェアを開発できないか...
DDD どうだった?
導入に失敗した
‒ (個人の感想です)
どうなった?
‒ 仕様を読み解くのが大変
‒ 以前に比べて生産性が下がった
‒ 品質も特に上がってない
DDD どうだった?
いいこともある
‒ 実装の共通化への意識は上がった気がする
‒ レイヤの役割は以前より明確になった
‒ まれに生産性が大きく上がることがある
失敗の原因
まぁ勉強不足
‒ 正しいけど話終わっちゃうので
‒ 以降の話はいったんこれを忘れてお聞きください
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
ひとつのモジュールに詰め込みすぎた
事象
‒ 全部同じ名前空間
‒ 文脈が分からないので使っていいか分からず、もしくは普通に見つからず再
利用が進まない
‒ 勇気を出して使うとある日突然全く関係ない(と思った)修正でバグる
原因
‒ ドメインモ...
ひとつのモジュールに詰め込みすぎた
反省
‒ とにかくドメインモデル(図)を書く
‒ 再利用は(いったん)忘れる
‒ 分けすぎは(多分)「継続的な統合」でなんとかなる
‒ 分けなさすぎを分けるのは大変
• 影響範囲とか
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
ユビキタス言語やモデル(図)がない
事象
‒ 文脈が読み取れないので影響範囲が分からない
‒ ドメインエキスパートが加わらない = 実装者の視点になってしまう
‒ 実装視点になる =「意図の明白なインタフェース」にならない
原因
‒ 面倒(実際...
ユビキタス言語やモデル(図)がない
反省
‒ 自分だけのものでよいので作る
‒ WHY を説明してもイマイチ
‒ それより、しつこく図を使って、価値があることを分かってもらう
• 何か話す時には図を見せながら説明する
• 何か質問されたらとりあ...
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
リポジトリだけ頑張りすぎた
事象
‒ 高度な抽象化と汎用性を兼ね備えた高機能リポジトリ
‒ Entity Framework を想像してもらったら大体合ってます
‒ 自分たちで作ってしまったので、リポジトリ追加するときが苦行
リポジトリすごい
上手く流用できると
‒ かなり便利で生産性も上がる
裏はどんな実装なのか?
‒ 式を全て Expression で保持
‒ SQL 発行直前に、Expression から自分で SQL 構築 ← え?
SELECT 文の作成処理
‒ つらい
リポジトリがあまり作られない
‒ 楽をするためにリポジトリラッパーが氾濫
• HogeGetService クラス
‒ どうしようもないときは既存クラスを拡張
• さらに巨大に
‒ つらい
リポジトリだけ頑張りすぎた
原因
‒ ひとつの集約や Entity に関わるテーブルが多すぎる
‒ インフラ層の課題をインフラ層で解決しなかった
• Entity Framework 使えない
• SQL が複雑で、複雑な抽出条件をもらわないと...
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
遅い
事象
‒ 遅ォォォォォいッ説明不要!!
‒ 具体的には Entity の復元が遅い
原因
‒ ひとつの集約や Entity に関わるテーブルが多すぎるので SELECT 遅い
‒ キャッシュしてないので SQL の発行回数が多い
‒ リフ...
遅い
反省
‒ DDD はインフラ層の問題を解決しない
‒ CQRS、キャッシュを検討する
‒ リフレクションによる自動化ではなく、テンプレートによる自動化
‒ 集約や Entity を小さく保つ
やらかし一覧
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
大きく始めた
事象
‒ 全実装の 1/5 がいきなり DDD に
‒ 失敗の予感を感じても方向転換したり引き返せない
‒ 今更違う設計にもできず、負債を産む機械になってしまった
原因
‒ レガシーを憎みすぎた
‒ 自分たちの力量を客観視できてい...
大きく始めた
反省
‒ 始めは小さく、段々大きく
‒ レガシー、意外といいやつじゃん
• 「Sansan はレガシーでよかったんですよ!」発言(実話)
‒ DDD にすべき箇所とそうでない箇所がある
やらかし一覧
なんでもサービスにしてしまった
ひとつのモジュールに詰め込みすぎた
ユビキタス言語やドメインモデル(図)を作らなかった
リポジトリだけ頑張りすぎた
遅い
大きく始めた
その他
その他
万能 Service
‒ 実装場所に困ったら Service
‒ 困って無くてもとりあえず Service
その他
ドメインモデル貧血症 or Fat Model
‒ サービスが万能過ぎて実際やることない
‒ 意識高い系 Entity (超でかい)
その他
お?Value Object ってフォルダがあるな。。。
‒ 開いて見てみる
‒ Value Object じゃなかった
_人人人人人人人人人人人人人人_
> Value Object じゃなかった <
 ̄Y^Y^Y^Y^Y^Y^Y^Y...
まとめ
どうしてこうなった
Iterative に作らなかった
‒ DDD ってこういうことねで実装 => 振り返りがないので間違いに気づけな
い
レガシーの課題を継承してしまった
‒ 新しい仕組みに気をとられて、レガシーの問題を整理できなかった
ドメ...
どうしてこうなった、からの
基本に忠実に、振り返りながら
‒ 特にドメインモデル(図)を必ず作る
• 面倒だけど絶対に役に立つ。上手く出来なくても過程だけでも大事
‒ 小さく始める
適用範囲を絞る
‒ レガシーも一概に悪ではない
失敗から学ぼう...
某S社のddd(メイリオ)
某S社のddd(メイリオ)
Upcoming SlideShare
Loading in...5
×

某S社のddd(メイリオ)

565

Published on

2015/08/07 DDD 勉強会

Published in: Software
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
565
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
1
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "某S社のddd(メイリオ)"

  1. 1. 某 S 社 の DDD -どうしてこうなった駆動開発- @kumake1004
  2. 2. 自己紹介 名前@kumake1004 ‒ Sansan 株式会社 アプリケーションエンジニア ‒ 2011年入社 (5年目) 仕事 ‒ 法人向け名刺管理アプリのサーバーサイド実装 ‒ アプリエンジニアとインフラエンジニアの板挟みにあうこと 興味 ‒ .NET (C#) / DDD / テスト / マネジメント
  3. 3. どうしてこうなった駆動開発とは 職場で DDD 導入したら失敗しました ‒ (個人の感想です) 再挑戦を始めたところ、、、 ‒ 漠然と思いはあって、良い機会なので振り返って言語化します ‒ という普通の失敗事例紹介 つまりただの出オチ
  4. 4. - 実践ドメイン駆動設計 コアドメイン (スクラム) における集約の使用 “彼らには DDD の経験があまりなかった。そのため、チームは DDD に関 してちょっとした間違いを犯した。” “最終的に彼らは、自分たちが集約を扱った経験を糧にして成長した。私達も 同じように成長できるはずだ。彼らの悪戦苦闘ぶりから学び、自分たちのソ フトウェアを作るときに同じ状況に陥らないようにしよう。”
  5. 5. DDD 導入の背景 名刺管理 Web アプリケーション ‒ C# / ASP.NET / PostgreSQL 他 ‒ 生まれて 8 年なので色々つらい(トランザクションスクリプトはやだ!) ‒ もっと早くて質の良いソフトウェアを開発できないか? どうやって? ‒ 3 年くらい前に大きな新機能追加がきた ‒ この機会に設計や実装を見直そう ‒ DDD っていうのがあるらしい。流行ってる
  6. 6. DDD どうだった? 導入に失敗した ‒ (個人の感想です) どうなった? ‒ 仕様を読み解くのが大変 ‒ 以前に比べて生産性が下がった ‒ 品質も特に上がってない
  7. 7. DDD どうだった? いいこともある ‒ 実装の共通化への意識は上がった気がする ‒ レイヤの役割は以前より明確になった ‒ まれに生産性が大きく上がることがある
  8. 8. 失敗の原因 まぁ勉強不足 ‒ 正しいけど話終わっちゃうので ‒ 以降の話はいったんこれを忘れてお聞きください
  9. 9. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  10. 10. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  11. 11. ひとつのモジュールに詰め込みすぎた 事象 ‒ 全部同じ名前空間 ‒ 文脈が分からないので使っていいか分からず、もしくは普通に見つからず再 利用が進まない ‒ 勇気を出して使うとある日突然全く関係ない(と思った)修正でバグる 原因 ‒ ドメインモデル(図)を書かないから境界が分からない ‒ 再利用の可能性を捨てきれない(お前が思っているほど汎用的ではない)
  12. 12. ひとつのモジュールに詰め込みすぎた 反省 ‒ とにかくドメインモデル(図)を書く ‒ 再利用は(いったん)忘れる ‒ 分けすぎは(多分)「継続的な統合」でなんとかなる ‒ 分けなさすぎを分けるのは大変 • 影響範囲とか
  13. 13. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  14. 14. ユビキタス言語やモデル(図)がない 事象 ‒ 文脈が読み取れないので影響範囲が分からない ‒ ドメインエキスパートが加わらない = 実装者の視点になってしまう ‒ 実装視点になる =「意図の明白なインタフェース」にならない 原因 ‒ 面倒(実際面倒) ‒ ドメインエキスパートが嫌がる ‒ チームメンバーも嫌がる
  15. 15. ユビキタス言語やモデル(図)がない 反省 ‒ 自分だけのものでよいので作る ‒ WHY を説明してもイマイチ ‒ それより、しつこく図を使って、価値があることを分かってもらう • 何か話す時には図を見せながら説明する • 何か質問されたらとりあえず図を出して考えるふりをする(実績あり)
  16. 16. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  17. 17. リポジトリだけ頑張りすぎた 事象 ‒ 高度な抽象化と汎用性を兼ね備えた高機能リポジトリ ‒ Entity Framework を想像してもらったら大体合ってます ‒ 自分たちで作ってしまったので、リポジトリ追加するときが苦行
  18. 18. リポジトリすごい 上手く流用できると ‒ かなり便利で生産性も上がる 裏はどんな実装なのか? ‒ 式を全て Expression で保持 ‒ SQL 発行直前に、Expression から自分で SQL 構築 ← え?
  19. 19. SELECT 文の作成処理 ‒ つらい リポジトリがあまり作られない ‒ 楽をするためにリポジトリラッパーが氾濫 • HogeGetService クラス ‒ どうしようもないときは既存クラスを拡張 • さらに巨大に ‒ つらい
  20. 20. リポジトリだけ頑張りすぎた 原因 ‒ ひとつの集約や Entity に関わるテーブルが多すぎる ‒ インフラ層の課題をインフラ層で解決しなかった • Entity Framework 使えない • SQL が複雑で、複雑な抽出条件をもらわないとデータアクセス出来ない、速度出ない 反省 ‒ 集約や Entity は小さく • Unit Of Work、結果整合性 ‒ インフラ層の課題をドメインモデルに寄せない • SQL リファクタリング、SQL チューニング、キャッシュ
  21. 21. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  22. 22. 遅い 事象 ‒ 遅ォォォォォいッ説明不要!! ‒ 具体的には Entity の復元が遅い 原因 ‒ ひとつの集約や Entity に関わるテーブルが多すぎるので SELECT 遅い ‒ キャッシュしてないので SQL の発行回数が多い ‒ リフレクション
  23. 23. 遅い 反省 ‒ DDD はインフラ層の問題を解決しない ‒ CQRS、キャッシュを検討する ‒ リフレクションによる自動化ではなく、テンプレートによる自動化 ‒ 集約や Entity を小さく保つ
  24. 24. やらかし一覧 ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  25. 25. 大きく始めた 事象 ‒ 全実装の 1/5 がいきなり DDD に ‒ 失敗の予感を感じても方向転換したり引き返せない ‒ 今更違う設計にもできず、負債を産む機械になってしまった 原因 ‒ レガシーを憎みすぎた ‒ 自分たちの力量を客観視できていなかった
  26. 26. 大きく始めた 反省 ‒ 始めは小さく、段々大きく ‒ レガシー、意外といいやつじゃん • 「Sansan はレガシーでよかったんですよ!」発言(実話) ‒ DDD にすべき箇所とそうでない箇所がある
  27. 27. やらかし一覧 なんでもサービスにしてしまった ひとつのモジュールに詰め込みすぎた ユビキタス言語やドメインモデル(図)を作らなかった リポジトリだけ頑張りすぎた 遅い 大きく始めた その他
  28. 28. その他 万能 Service ‒ 実装場所に困ったら Service ‒ 困って無くてもとりあえず Service
  29. 29. その他 ドメインモデル貧血症 or Fat Model ‒ サービスが万能過ぎて実際やることない ‒ 意識高い系 Entity (超でかい)
  30. 30. その他 お?Value Object ってフォルダがあるな。。。 ‒ 開いて見てみる ‒ Value Object じゃなかった _人人人人人人人人人人人人人人_ > Value Object じゃなかった <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ^Y ̄
  31. 31. まとめ
  32. 32. どうしてこうなった Iterative に作らなかった ‒ DDD ってこういうことねで実装 => 振り返りがないので間違いに気づけな い レガシーの課題を継承してしまった ‒ 新しい仕組みに気をとられて、レガシーの問題を整理できなかった ドメインモデル(図)を作らなかった ‒ ドメインエキスパート視点での関心事を明確に出来ない ‒ メンタルモデルと実装が結びつかないので冗長になっただけ
  33. 33. どうしてこうなった、からの 基本に忠実に、振り返りながら ‒ 特にドメインモデル(図)を必ず作る • 面倒だけど絶対に役に立つ。上手く出来なくても過程だけでも大事 ‒ 小さく始める 適用範囲を絞る ‒ レガシーも一概に悪ではない 失敗から学ぼう ‒ どうしてこうなった?と思ったときはある意味チャンスでもある ‒ ささいな失敗経験の積み重ねが応用に活きてくるので、みんなも失敗事例を共有してください
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×