by shigemk2

当面は技術的なことしか書かない

DDD入門 #ScalaMatsuri #sm_c

講師不在☆だった

  • 業務ドメインと開発を結びつけよう
  • 技術的な関心事とドメイン知識がいっしょくたになってしまう
  • 営業と開発の垣根をなくして共通言語で話していこうという話

GANMA!でDDDをやってみてから1年くらいたった

Septeni

GANMA!をDDDで作ってみたので、実際にどういう仕組で作ったのかを話

ganma.jp

  • DDD/なんか前職ではやっていた
  • DDD本を有給消化中で読んだ
  • ユビキタス言語や構造を考えてみる

漫画のモデリング

  • GANMA!の配信業務
  • 漫画雑誌を「マガジン」
  • 「ナルト1話」「ワンピース1話」を「ストーリー」
  • 一連の話を「ストーリー」

業務

  • 閲覧系
  • 管理業務

ストーリー

  • Story ID(Entity)がある
  • Author 作者
  • ページ
  • サブタイトル

それぞれを型とかtype aliasで定義している

  • ストーリーリポジトリ
    • 取得/登録/更新/削除
  • ドメイン層には言葉しかかかないようにする
  • DBへのアクセスはインフラ層

  • シリーズ(ワンピース/読み切りなど)

  • シリーズリポジトリ
  • マガジンクラス
    • ストーリー
  • マガジンリポジトリ

悩んだ

  • IDはinsertするまでIDを触れない
  • 採番テーブルを作ると手間
  • UUIDを使う

DB→Entity

  • Infra/EntityはDomain層
  • DAO/ドメイン層に生データ/Entity変換のメソッドかクラスを設ける

  • APP層でやっている

  • RepositoryとTable操作系でobjectにしたのでテストやりづらい
  • テストが大変
  • コンテキストが絡まざるを得ないことをするときも大変
  • DI出来るように

よかったこと

  • ドメイン層に余計なことを徹底的に書かない

質疑

  • IDを持っていない状態のEntityは…
  • UUIDを使うことのメリット
  • テーブルはSQLアンチパターン
  • 開発が決めたことをまとめる
    • コンテキストのマップ
    • リポジトリのキャッシュ
  • キーワード決めは開発。理解を得るところは営業とは話し合い。政治力。
  • type aliasと加えて、case classなども使う
  • 用途を間違えなければNoSQLでも可

ScalaとDDD かとじゅんさん

  • オブジェクトやモデルをおさらい
  • ペットショップのドメインを事例に

DDDのまえにOOP

  • OOPはなんのため?
    • デザインパターンのため? 不是
      • メルカトル図法はモデリング 面積はデタラメ
      • 文脈があって 手続きがあるとMVCとは言わないのでは
      • ユーザーの頭の中にあるものとモデルを結びつける
        • 頭のなかにあるものを実装に写しとること
    • モデルはテーブル? 不是
    • シナリオを選ぶ モデルを考える モデルを実装する
    • ドメインモデルでは振る舞いが大事

ペットショップの例を考える

  • ホワイトボードに何かを書く
  • 型が制約をあらわす
    • ペットとペット以外の商品を同じように扱う
    • 現実の業務と密接に絡んでくる
    • 精算時に注文がなければダメなのでは
    • エンティティの実装(値そのものではない)
    • IDを持っていないエンティティは例外扱い 基本はエンティティにIDが存在する
    • CPUとメモリだけでIDを採番出来るようにしたい
      • ID型はなんでもいいが、識別子を保持して、絶対変更してはいけない
    • 顧客を表すエンティティ 属性が多すぎるのは良くない

ライフサイクルの責務を分離

  • グローバルエンティティ/リポジトリ/ファクトリ
  • 集約はIOの最小単位
    • これを検索するのがリポジトリ
    • 集約はテーブルではない それはエンコードの一つではない
  • リポジトリをサポートするtrait
    • リポジトリはDAOではない
    • 遅いストレージに合わせてIFを実装する必要
      • インピーダンスミスマッチ

質疑

  • RDBよりKVSのほうが相性はいいけど、KVSはインデックスを使った問い合わせがほとんど出来ないので注意
  • repositoryのメソッドがtryで囲われているのはやりすぎ…?→IO関係の都合上そうしてる