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

実践ドメイン駆動 第6章メモ

開発 DDD

実践ドメイン駆動設計

実践ドメイン駆動設計

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計 (Object Oriented Selection)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

値オブジェクト6.1〜6.4

  • 値の利点を知る
  • 可能な限りエンティティのより値オブジェクトでモデリングすべき
    • 参照透過性かな?

6.1 値の特徴

  • 計測・定量化・説明
  • 状態不変
  • 概念的な統一体
    • 複数の属性が互いに関係、一つだけ取り出しても意味が無い
    • 例:50,000,000ドルには2つの属性(50,000,000とドル)があって、どちらか片方だけ取り出すと別の意味になったり、意味がなかったりする
    • 属性とプロパティの違いはなにか?
    • プロパティ名や値型の名前は境界づけられたコンテキストとそのユビキタス言語が定まってからでないと決められない
    • 標準の型にパッチをあてて特別な振る舞いをさせるのはおすすすめしない
      • 型付が要請されてるように読める
  • まるごと置き換えられる
    • オブジェクトの属性を変更する必要があるからエンティティ => その前提をうたがう(置き換えでよいのではないか?)
  • 値の等価性
    • 値オブジェクトのインスタンスを比較するときにオブジェクトの等価性をたしかめる
    • 属性が全て同じで同じ型のオブジェクトであれば入れ替えられる
    • 集約の一意性に対応 => 値の等価性は集約のインスタンスを識別子で特定するために必要
      • 一意な識別子は不変である必要がある
      • 交換可能性は不要だけど、不変であったり、副作用のない振る舞いが必要ならば値型にする
  • 副作用のない振る舞い
    • オブジェクトの振る舞い => 副作用のない関数
      • 関数:何か出力するけど、オブジェクトの状態を変更しない
    • 不変であること => 副作用がないことを満たす必要がある
    • クエリメソッド => オブジェクトに問いかけるメソッド、答えが変わってしまってはいけない
      • 関数型プログラミング言語
      • 名前を変更するときは都度値を生成する(rubyのselectとかのイメージ)
      • 値オブジェクトのメソッドにエンティティを渡す => エンティティが変更されていないことを証明するのは難しい
      • 渡すのは値にしておくと明快
      • プリミティブな型 => 専用の型 => のように検討を重ねてモデルを継続的に改良
      • エンティティに持たせるべきでないロジック => ドメインサービス
  • なんでも値オブジェクトもダメ => シンプルな属性で充分な場合もある

6.2 ミニマリズムを考慮した結合

  • 上流のコンテキストからオブジェクトを受け取る => 下流のコンテキストでのその概念のモデリングに値オブジェクトを使うようにする
    • 下流のモデルで管理スべきプロパティの数を最小限にできる、不変な値なら責務も少なめに抑えられる
    • 認証アクセスコンテキスト User, Role(モデレータというRoleがある)
    • コラボレーションコンテキスト Moderator
      • 上流ではモデレータになるユーザを2つの集約で表現
      • 下流ではModeratorという値オブジェクトで表現
        • ModeratorはCollaboratorのサブクラス
        • 上流の集約が多数の属性を保持しているが、下流の値オブジェクトで必要な属性のみもつようにする
          • 影響を最小化
    • 下流のコンテキストのオブジェクトをリモートのコンテキスト内の集約と同期 => 集約を下流のコンテキストに置くよう設計
      • エンティティを使って変更を保持するから
      • できれば避けたい

6.3 標準型を値として表現する

  • 何かのものについて説明するためのオブジェクト
    • よくわからん => 後の例をみると単位とかそういうものをについてか?
    • 認識としてはあってるみたい
  • 電話番号の種類(Home, Mobile, Work, Ohter)、金額(通貨単位)
  • 開発のライフサイクルの管理に標準型を使うことも出来る、投与方法(点滴・経口・塗布など)でも
    • こういうのはエンティティとして扱う => 標準型を扱う側の話?
  • 標準化のレベル(アプリだけや国の規格、国際標準規格)
  • Javaenumを標準型の例
    • ステートオブジェクト
  • enumが気に入らないなら、一意な値のインスタンスを使う方法もある
    • サービスやファクトリを使って必要に応じてインスタンスを静的に作成
    • DBにマスタとして登録しているような場合などに使えそう

6.4 値オブジェクトのテスト

  • ドメインモデル内のさまざまなオブジェクトがクライアントからどのように使われるのか、クライアント側がそれらのオブジェクトに何を期待しているのあ
    • 設計の際に重要 => クライアントの視点を気にすること
  • チームの標準に対応するテストを書く必要がある
  • はじめに作ったインスタンスからコピーを作って、比較
    • コピーとオリジナルが変わってなければOK
    • 操作したあとに比較して変わってなければOK
  • モデルのテストはドメインの意図を含めること

このあたりになってくると、プログラミング言語としては型が付いているほうが嬉しい感じに見えてくる。