読者です 読者をやめる 読者になる 読者になる

mo-fu note

技術のこととか色々書きます

DDD Alliance! ドメイン駆動設計をやってみた 6つの現場からの報告に参加した

自分用のメモ TL;DR

イベントページ

http://ddd-alliance.connpass.com/event/21932/

ビッグローブでの2年間の取り組み

DDDを組織で始めるための考え方

  • 途中から参加
  • 現場 ←→ 経営層
    • 相手の立場になると「あーわかるわー」ってなることがあるので、そこを汲み取って行くのが大事

開発現場から学んだドメイン駆動設計中心のサービス開発

  • DDD適用サービス
  • Wi-Fiスポットから
  • 5チーム30人でDDD実践
  • 100名規模でやっていきたい
    • DDDの価値を共有
    • 課題分析と課題解決
    • 人材育成
    • 新たな技術にチャレンジ
    • 開発環境の高度化もやる
  • DDDを採用する価値とは
    • 価値の最大化関心事が何か?明確化
    • サービスを継続することが前提
    • ISPにある特性・特徴?
      • 変更し続ける
      • 成長し続ける
      • 使われ続ける
  • 独自言語だとつぎはぎの機能強化
    • 費用かかるよ
    • サービスが終わるまでのトータルコストの削減
  • トータルコストの削減
    • 変更コストを下げる
    • 属人性を下げる
    • 業務をコードで表現
  • チーム環境の考え方
  • 業務フロー図
  • コンテキストマップ
  • 初期ドメインモデル
  • 状態遷移図
  • ユースケースフロー図
  • ケルトンコード
  • DB設計

立ち上げ時の心構え

  • 初期はわからないことだらけ
    • 方向付けレベルの設計に留める
  • コアドメインを議論することがサービスを理解する第一歩
    • 企画の人とかとディスカッションする
  • サービスの複雑性と向き合う
  • ドメインモデルとコードを結びつける
  • 設計者と実装者を分離しない
  • コアドメインの設計と実装は重点的に
  • プルリクエストのWIPを活用、効率的にレビュー
  • スプリントごとにドメインモデルから重要な概念を追加、不要な概念を削除
  • 普段の会話のぎこちなさに敏感になる
  • 書き言葉と話し言葉がずれたら警告
  • ドメインを見逃さない
    • ドメインモデルと実装を改善するプロセスが必要

チームビルディング

  • ソフトウェア開発はチーム
  • チームメンバーで相乗効果を発揮
  • 要求が絶えず変化するので知識の共有が大事
  • DDDにおけるチームビルディング
  • リーダーは方向性を定める、絶えず少しづつ変化する、双方向のフィードバック
  • DDD的に必要

大事なこと

  • 全員で設計する
    • メンバー全員が考える(会議の時にパソコンとかいじってるとかだと困る)
    • メンバー全員の意見を引き出す
    • メンバー間のギャップを無くす
  • メンバー全員が同じ地図を持って理解するため
  • 設計の目的と効果をメンバー全員が理解して実践するため
  • 熟練者のノウハウを経験が浅いメンバーに伝授するため
  • モデリング済みの部分も積極的にモデリング
  • 経験が浅いメンバーはモデリングする機会を増やすことが成長につながる
  • 新規加入メンバーはドメインを理解するチャンス
  • モデリングはメンバー全員に実施させる
    • 設計力が上がる
    • 変化コスト、属人性を下げる
  • ユースケース
    • Biglobe非会員
      • Webから申し込む
    • Biglobe会員
      • 管理画面に入って
  • コンテキストマップを作る
  • ドメインモデル

  • 入会可能条件

    • 20歳以上
    • コースは「ニコニコ」?「なんとか」
    • アプリケーション層の入会サービス
    • データソース層、会員リポジトリ
  • イミュータブルデータモデル

    • 業務履歴をひたすら記録(insert)
    • 変更業務でUpdateすると記録の改ざん...?
  • Eventテーブル
    • 業務が発生するとひたすらinsert
  • Stateテーブル
    • 業務が発生するごとにupdate
  • 入会イベント、退会イベント

    • 会員テーブルと、退会用のテーブルがある
    • 業務が発生すると関連するテーブルに業務履歴を記録(insert)
  • ミュータブルデータモデル?

    • 会員テーブルのみ
    • 退会時にnull から 退会日が入る
  • 契約エンティティに対するDB設計の場合

    • 申込テーブル
      • 申し込みIDをFK でキャンセルテーブル
    • 契約テーブル、申し込みIDをFK
    • ステータステーブル、申し込みIFをFK
    • 解約テーブル 申し込みIDをFK
      • 解約キャンセルテーブル解約IDをFK
    • そもそも解約が少ないという前提がある

失敗談

  • 20個くらいあった
  • 5個紹介するよ
  • ドメインモデルが古い
    • 日々変化するドメインモデルが最新化されない
    • Keepのドメインモデルは重要な概念や本質のみ
  • Policyクラスの乱立
    • 業務チェックのため
    • エンティティに業務ロジックが抜けていく
    • bundleSource
  • Repositoryのsaveメソッド
  • 他集約のRepositoryを操作
  • SQLに業務ロジックが混在
    • SelectのWhere句に業務ロジックが混在
    • 検索条件は主キーのみにして、ステータスの絞り込み条件はドメイン層で記述
  • DDD本と現場での実践を行ったり来たりして理解を深めていくことが重要

ドメイン駆動設計をしているプログラマーの悩み

  • そら製作所
  • DDD.javaとか主催しているよ
  • DDDを実践していて、主にプログラミングの面で悩んでいること
  • 背景
    • Java, B to C, Webアプリ, 人材
  • UI, Service, DataSorce が DomainModelに
  • Spring MVC
  • 永続化層
    • MyBatis
    • BeanValidation
  • モデルの歪みに気付けるか
    • モデルにロジックを集める方向に作りやすくする
  • RDBからのAggrigate復元
  • UI はすぐ変わる...
  • Validation
    • Javaのオブジェクトへの変換はそんなに辛くない
    • 「何か」からJavaのオブジェクトへの変換がつらい
  • いろいろ言ったけど、なんとかなってるので怖がらずに実践していきましょー

ドメイン駆動設計におけるシナリオテストの活用

  • DDD Allianceの設立メンバー
  • TDDとかの勉強会やってるよ
  • シナリオテストを顧客と合意する手段として
  • BDD/シナリオテスト
    • 1つまたは複数ユースケースをスペックとして記述
    • プレゼンテーションから見た振る舞いをテスト
  • 導入の動機
    • 仙台を拠点にリモートワークで受託開発
    • 顧客は東京
    • チームメンバーは全国各地
  • プレゼンテーション層を実装したタイミングで、顧客から大量のフィードバック
  • 毎週成果物をリリース
  • ビジネス的なプロ濁度の優先度や仕様が常に変わっていく
    • 営業サイドからのフィードバック
    • プロダクトを売るためには出来るだけ早く、具体的なものを開発する必要がある
  • TDD大好き
    • 仕様合意を進め、出戻りを減らしたい
    • BDDをベースにしたシナリオテストを試作
    • Spock Framework
  • コンテキスト図、ユースケース図、サイトマップドメインモデル、ユビキタス言語
  • シナリオテスト、ユニットテスト
  • プレゼンテーション層、サービス層.....
  • 退職者管理の開発事例
    • 業務に精通した人の再就職を促す
  • 実際のシナリオテストの例
    • def, when, then, and
  • 開発への濃淡、ちゃんとした実装は後回し
  • リズム感、仕様の合意ができれば、実装にスピード感が出る
  • 打ち合わせでは、声に出して読み合わせ
  • どこまでシナリオテストを作りこむか、代替シナリオ
  • 画面を作るタイミングとのトレードオフ
  • いい感じだからみんなもやってみてください

ECサイトのリプレイスをDDDでやってみた

  • 大日本印刷hontoビジネス本部
  • ECサイトhontoのサーバサイド
  • DDDをチームメンバとともに、社内布教活動を実施中
  • honto
  • サービスを小さい単位に分割していきたい
  • 某殿堂の圧縮陳列
    • ド◯キ
  • ソフトウェアを利用する人の活動や関心事を理解し、オブジェクトとして表現
  • やってみたよ
  • ドメインエキスパート不在
    • 開発当初の意図、目的を把握している人がいない
    • 結果として、知識を噛み砕ききれていないモデルを表現しただけになった
  • 実装
  • ドメインモデル貧血症を患っている
  • 注文を表現する際に、振る舞いを切り捨ててしまった
  • チームでもっと言葉を使ってモデリングするべきだった
  • 自身のスキルアップも兼ねて、読書会等を継続的にやったけども毎回参加するのは数名...
  • 人が減ってきてしまった
    • 参加を促したり、PRで実コードから興味を引く
    • 今は実践ドメイン駆動設計の本を読んでいるよ、参加者増えた感じするよ
  • 正解はないけど、チームで言葉で話して、納得できたらそれが正解
  • DDD本と実装の反復作業がより理解に繋がる
  • hontoは人を募集しています

ガチDDDを経て

  • アソビュー株式会社
  • ドメインを見つけて小さく作りなさい
  • 1メソッド3行、1クラス50行以内
  • if文はバグを生んでいるぞ
    • くらいの気持ちで
  • リファクタリングの8章 + enum
    • 気づきを得た転換期
  • エヴァンスの本を読み合わせしたりして知識を高め合うのも大事
  • 実際に手を動かしてお手本なり導入を続けるほうが重要なのかもしれない
  • 人を募集しています。
    • どこもエンジニアが足りてなさそう

ドメイン駆動設計のススメ

  • オブジェクト指向の活用
  • 悪しき習慣
    • 基本データ型でプログラミングする
    • 動いたら設計をやめる
      • 動いたコードを見ない/触らない
      • 業務のことを表現できている?半年後に罠にはまらない?
    • コードを書く前にドキュメントを準備する
    • 分析/設計/実装を別の人が担当する。別の日にやる、工程を分ける
    • 正解はないけどね
  • 身に付けるべき習慣
    • 独自に定義した型をどんどん作る
      • 「氏名」「住所」「電話番号」
  • 動いているコードの設計改善に時間をかける
    • まずコードを書いて動かす
    • 動いているコードに対して議論する
  • ドキュメントはコードから生成する
    • 生成できるようにコードを工夫する
  • 分析/設計/実装を同じ人間がやる
  • 毎日分析し設計し実装する
  • ドメイン駆動設計はオブジェクト指向とXPを現場でどうやるか
  • 学び方: 知識
  • 学び方: 現場での体験
    • 目の前で動いているコードを対象に
    • 設計改善の議論をする
    • 動いているコードを変更する
    • 設計の違いの効果を実感する
  • ドメイン駆動設計
  • XPのケント・ベックの言葉
    • どんな状況でも改善できる
    • あなたから、今日から改善をはじめられる