2015-12-16 某S社、出直しDDDってるってよ

788
-1

Published on

2015/12/16 Sansan DDD 勉強会#2

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

No Downloads
Views
Total views
788
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
1
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • ここまでで5分
  • Expression は必須ではなかったが、サンプルが Expression を多用した作りだったこともあり、多くが Expression を使った実装となった
    ステートフル -> 関数型な人が聞いたら涙がちょちょ切れる
    DB 接続するのにどういうことだってばよ?
    -> immutable とは言っていない。mutable なインスタンスフィールドがなければステートレスと言える
    ↑クライアントはインスタンスの状態の変化を気にする必要がない
  • 行数を見せる
    Expression をこねている部分を見せる
    ステートフルなところを見せる
  • まず Base っていうクラス名にビビる
  • ここで15分
    DDD っていうかアーキテクチャ
  • Transaction Script: 主にバッチを想定
  • EF は基本 DDD と馴染みがよく、それほど大変ではない
    やったこと
    Sansan.Data: sharding 対応
    EF の基本形は config に connection string を書く方式だが、Sansan では DB を sharding しているため不可
    プログラム実行時に EF に connection を渡す仕組みが必要
    データアクセス基盤は、現在の Logical Call Context における接続先 shard を決定し、connection を返す
    Npgsql のパッチ
    bit(n) 対応
    TransactionScope 対応
    DbContext はステートフルなので、Logical Call Context に閉じる形にすることで、Repository のステートレスを実現
    Dapper との組み合わせ
    EF を利用した DDD で大変なのは、EF のベストプラクティスを探すこと
    ドキュメントを探しても、ベストプラクティスは見つからず、カタログスペックしかない
    例えば
    適切な CLR Type の選択
    Navigation Property はどこまで繋げるか -> Aggregate 内まで
    ComplexType の使い方
  • ここで30分
    * 実装以外で、某 S 社がどうやって DDD を進めているか
    * まだリリースまで至ってないことに注意
  • 小さく始めた
    一つのチームで
    一つの機能(Bounded Context)で
    Product Manager をドメインエキスパートに任命
  • 実装からのフィードバックはチームで相談
    曖昧にしない
    ドメインエキスパートが理解できない単語は使わない
    利用意識を徹底
    「ダムの決壊も蟻の巣から」
    間違った使い方、異なる言い回し、新しい単語に過敏に反応
    ユビキタス言語警察
  • ネーミング (実装) にこだわるように
    極端な例: いちメソッドシグネチャ => 26コメント
    成果と同時に課題でもある
    実装ではなく、ユビキタス言語の方を議論すべきでは?
    日本語のユビキタス言語を作るときに英訳を同時に作れないか?
    https://github.com/eightcard/lk-linkknowledge/pull/4625
  • 最初は、、、
    機能の担当者が作って共有
    課題
    深く理解するほど見ないので存在する意味が無い
    担当者のためだけなら大げさにこんなの作らなくてもいい
    議論しないので蒸留されていかない
    スケジュールに追われてモデルの更新が追いつかなくなってきた
    これらの課題をどう改善していくか?
    http://www.slideshare.net/maoohnishi3/20151110-54980095/60
  • ドメインモデルはみんなのもの
    週一回、モデリングミーティングの時間を作った
    みんなで考えるので、皆が十分に理解できる => モデルをみんなのものにできる
    モデリング済みでも気にしない
    この写真は実際に一度モデリング済みだったもの => 古かったものを最新に => 議論した結果、新しいモデルに
    旧アーキテクチャで実装せざるを得ないと思っていた(し、実際してた)が、新アーキテクチャに乗せられることが分かった
    他にも良いことがある
    モデリングの能力を高められる(知見の共有)
    モデリングの質を高められる
  • DDD を実践してどうなったか?
    共通認識によってコミュニケーションが増えた

    PM へのフィードバック
    用語集なんかは顧客の物をドキュメントに起こしただけ、顧客 => 開発への一方通行
    ユビキタス言語やドメインモデルはプロジェクト全体の理解
    実装を進めておかしいところがあれば、PM に自信を持ってフィードバックできる
    PM と開発の双方向のやりとり

    間違った方向へ進もうとしていることに早めに気付けるように
    検証
    機能を設計や実装している
    既存の理解とズレているところが見つかる
    考えたことが間違っている or 現在のモデルが間違っているので、問題が潜んでいることに気付ける
    開発終盤のあるいはリリース後に気付く問題に、開発中に気付ける
    バグという意味もあるし、しなやかでない設計を指すこともある(どっちかっていうと後者)


  • 新人がいたので感想を聞いてみた
    このプロジェクトには途中参加
    プロジェクトが担当する機能についての知識も浅い

    最初はきつい
    どうしてもハイコンテキストにはなってしまうという背景
    実際、新人でなく我々も他チームとのコミュニケーションにちょっと苦労することもある

    ドキュメントが役に立った
    面倒くさがらずに作ろう

    PM と「会話 (議論)」できるようになった (新人 Y の証言)
    今まではよほど変なことを言われない限り言われたことに従っていた
    「そういうもの」という諦め
    ドメインの理解が不足していて、自分の意見に自信が持てない
    ユビキタス言語を大切にするという方針に従って、、、
    違和感を覚えたらすぐ確認
    議論にも自信が持てるようになった
  • きれいなドメインエキスパート不在
    ユースケース図を理解し、(簡素な) クラス図をも理解する非実在ドメインエキスパートを探して
    実装からのフィードバックをモデルに反映させられないことがある
    ドメインエキスパートが課題を理解できない
    DDD の意義と意図をもっと共有していかないといけない
    初期コスト
    構築して議論して深めるというプロセスは間違いなくプラスになっているが、同様に間違いなくコスト高
    体感で倍はかかってる
    好き勝手にクラスやメソッドを追加できない

    旧体制のままの開発プロセス
    変更に強くしたが、変更されない (機会が少ない)
    ウォーターフォール&ビックバンリリース
    変更に強くするにもコストがかかっている
    回収するために、小さな変更を繰り返しリリースする
    ユーザーにとってもメリットがあるし、会社にとっても素早くフィードバックが得られるはず
    プロジェクトごとに作られるチーム
    集合 => 解散 => 集合
    「のれん分け」による展開を目指して
  • 終わる頃には45分弱
  • 2015-12-16 某S社、出直しDDDってるってよ

    1. 1. 某S社、 出直しDDDってるってよ @atsukanrock & @kumake1004
    2. 2. 自己紹介 @atsukanrock @kumake1004
    3. 3. 前回までのあらすじ DDD (どうしてこうなった駆動開発)がスベった
    4. 4. DDD に挑戦したが、失敗 • どうして? • ドメイン駆動しなかった(ユビキタス言語?何それ?) • チームの意思を統一できなかった • 旧アーキテクチャを切り離せなかった • 大きく始めた • 次はどうする? • 実装以外の部分も大切にする • 旧アーキテクチャと切り離す • 小さく始める
    5. 5. 出直しの背景 いろいろつらかった
    6. 6. 自作 Repository (v2 Repository *1) がつらい • 作るのが大変 & レビューしづらい & 変更するのが大変 • 各具象 Repository の実装で Expression をこねる • Expression -> SQL 変換が自前 • 各具象 Repository のコード量が多い • ステートフル • Unit of Work がない *1: v2 アーキテクチャにおける Repository のこと。その前には v1 アーキテクチャもあった
    7. 7. v2 Repository の例 • インターフェイス部分 https://github.com/eightcard/lk-linkknowledge/blob/master/common/Repository/StackRepository.cs • Expression -> SQL 変換部分 https://github.com/eightcard/lk-linkknowledge/blob/master/common/Repository/Npgsql/StackQueryBuilder.cs
    8. 8. 旧データアクセス基盤がつらい • 自作の sharding 対応データアクセス基盤だが… • データアクセス基盤なのになぜか HttpContext に依存 • マルチスレッドで壊れる (ことがある) • ステートフルオブジェクトをキャッシュ • デバッグ実行しても何が起こっているか分からない
    9. 9. 旧データアクセス基盤 • HttpContext に依存 https://github.com/eightcard/lk-linkknowledge/blob/master/common/Base/Base.cs • ステーフル https://github.com/eightcard/lk-linkknowledge/blob/master/common/Base/DbmsHelper.cs
    10. 10. このままではまずい • 新しいアーキテクチャを考案すべき • リスク比較: 新旧アーキテクチャの混在 ≪ v2 Repository が量産され続ける • アーキテクチャ移行戦略: がんばる (しかない)
    11. 11. 出直し後の DDD その一部をお見せします
    12. 12. 選択式アーキテクチャスタイル • 実装する機能の性質に応じて以下から選択 • Transaction Script • Dapper を使う • Domain Model (DDD) • Unit of Work あり: Entity Framework を使う • Unit of Work なし: Dapper を使う • DDD アーキテクチャにも向き不向きがある • 例: 大量更新が前提のバッチアプリケーションには不向き • スタイル選択チャート https://sansan.atlassian.net/wiki/pages/viewpage.action?pageId=26050721
    13. 13. Transaction Script using Dapper
    14. 14. Domain Model using Entity Framework
    15. 15. Domain Model using Dapper
    16. 16. Layer をきちんと分割する • Layer 毎にアセンブリを分ける • Layer の依存関係をアセンブリの依存関係で強制 • アセンブリの循環参照はできない (ビルドエラー) • テクノロジー依存部分は Infrastructure Layer に閉じ込める • インターフェイスは Domain / Application Layer に • DI によって実装クラスのインスタンスを注入 • ユニットテスト時に Mock を挿せるように
    17. 17. Component の責務を正しく理解する • Component とは Entity とか Repository とかのこと • 誤認識の実例: • Application Service と Domain Service が区別されていない • DTO が Value Object と呼ばれている
    18. 18. Bounded Context を切る • 関心の分離 • 名前空間や Entity の肥大化を防ぐ • カラム数が多いテーブルでも、Bounded Context を切れば 対応する Entity の肥大化を防げる • 1 つの Bounded Context から見れば必要なプロパティは少ない • Namespace Guideline https://github.com/eightcard/lk-linkknowledge/blob/33t/coding- standard/feature/csharp/Document/CodingStandard/CSharp.md#名前空間の名前
    19. 19. v3 Repository (Code Name: Relaxed Repository) • Entity Framework (EF) Code First を採用 • Expression をこねない • SQL 構築は EF にやらせる • そもそも DbContext は Unit of Work + Repository https://msdn.microsoft.com/library/system.data.entity.dbcontext.aspx • インターフェイスを切って薄くラップすれば良い • 新データアクセス基盤 (Sansan.Data) を利用 • ステートレス • 議論の跡 https://sansan.atlassian.net/wiki/display/~kanbara/Relaxed+Repository
    20. 20. Domain Event (詳しくは次回以降に) • 主たる Domain ロジックから副次的な処理を切り離す • 例: メール通知、行動分析 / 監査用ログ収集 • メッセージングテクノロジー (例: Amazon SQS) を利用する • Fault Tolerant になる • 共通的なリトライの仕組み • 何度やっても成功しなかった処理は Dead Letter Queue に残る • 並列分散処理により高速化が可能 • 設計は複雑化する • Distributed / Compensating Transaction
    21. 21. 出直し後の DDD チームビルディング
    22. 22. 体制と方針 • DDD をやるという意思統一 • ドメインモデル図、ユビキタス 言語を見える形で作る
    23. 23. ユビキタス言語 • ドキュメントを作成 • https://sansan.atlassian.net/wiki/pages/viewpage.action?pageId=2123375 2 • PM との会話やユースケースで出てくる単語を拾う • 実装からのフィードバックはチームで相談 • 利用意識を徹底
    24. 24. ユビキタス言語へのこだわり
    25. 25. ドメインモデル
    26. 26. 全員でモデリング
    27. 27. どうなった? • ドメインについての共通認識を持てた • 以前より気軽にチームメンバに相談できるように • 相談を繰り返して共通認識がさらに強化される正のスパイラル • 開発から PM へドメイン知識のフィードバック • 間違った方向へ進もうとしていることに早めに気付けるように • ユビキタス言語、ドメインモデルが考え方の基準になる • 今考えていることと比較、検証 • 実装が業務を反映 • 会話の内容と実装が同じなので読んで理解もしやすい
    28. 28. 新人にとってどうか? (新人 Y の証言) • 最初はきつい • 入りたては何言ってるか意味不明(ハイコンテキストになる) • 慣れたらむしろ楽 • ドキュメントが役に立った • 意味が統一されているので、一カ所理解すれば全体の理解に繋がる • 新人による再モデリングという解決 • http://www.slideshare.net/maoohnishi3/20151110-54980095/71 • ドメインエキスパートと「会話 (議論)」できるように • ドメインの理解が不足していて、自分の意見に自信が持てていなかった • ユビキタス言語&モデルで PM と対等に議論ができるように
    29. 29. 課題は? • ドメインエキスパートにもっとフィードバックを • 「画面デザイン仕様書だけあればいいじゃん」 • ドメインモデルでの会話が難しい • 初期コスト • ネーミング、ユビキタス言語やドメインモデルの構築 • 旧体制のままの開発プロセス • 変更に強くしたが、変更されない (機会が少ない) • プロジェクトごとに作られるチーム • どうやって知識を継承していくか?
    30. 30. ご清聴 ありがとうございました

    ×