4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ミライトデザイン社内勉強会#15】「IDDD本から理解するドメイン駆動設計」輪読会~第6章「値オブジェクト」~

Last updated at Posted at 2021-02-06

前回の記事

【ミライトデザイン社内勉強会#14】「IDDD本から理解するドメイン駆動設計」輪読会~第5章「エンティティ」~ - Qiita

実践DDD本 第6章「値オブジェクト」~振る舞いを持つ不変オブジェクト~ (1/4):CodeZine(コードジン)

例えば、ユーザーエンティティの値オブジェクトである住所とかがRDBでは別テーブルになっているとき、値オブジェクトの実装がどうなるのか知りたい

  • テーブルがこんな感じになっていて
ユーザーテーブル 住所テーブル
ID ID
--------(なんかその他の値とか) ユーザーID
-------- 郵便番号
-------- 都道府県
-------- 市区町村
  • クラス図ではこうなっている
    • DBでは住所テーブルがユーザーIDを持っているけど、値オブジェクトの住所はユーザーIDは持っていない。
      • 住所の値オブジェクトがユーザーIDを持っているのは違和感あるので、、
スクリーンショット 2021-01-24 14.30.12.png (35.9 kB)
  • ユーザーと住所のテーブルが別れている場合、住所をDBに保存するときは、userIdが必要になる
interface UserRepository
{
    public function add();
}

class DbUserRepository implements UserRepository
{
    public function add(User $user)
    {
        $dbUser = new Eloquent\User();  // 適当LaravelのModelクラスみたいなイメージ
        $dbUser->id = $user->getUserId();
        $dbUser->save();
        
        $address = $user->getAddress();
        $dbAddress = new Eloquent\Address();
        $dbAddress->郵便番号 = $address->get郵便番号();
        // ... その他の値も全部詰める
        $dbAddress->save();
        
        // 住所の値オブジェクトにはuserIdは存在していないけど、DB保存では使用する。
        // みたいなことはしてもいいの?
        $dbAddress->userId = $user->userId(); 
        $dbAddress->save();
    }
}

  • テーブルで分ける必要があるのであれば、別にこれで違和感はない。
  • DBはパフォーマンス都合で作って、クラスはモデリング都合で作りたいので、DBとクラスの実装が別れていても問題ない。
  • 保存方法はRepositoryに任せる。
    • そもそもRDBとも限らない。保存する、取り出せることが重要なので、保存方法はなんでもいい。
    • 場合によってはtextファイルに保存しても別にいい。RDBだからモデルと結びつけて考えしまっているけど、textファイルに保存するための実装とモデルの実装が関係ないことはわかると思う。
    • Repositoryで重要なのは集約単位で扱えることなので、クラスのモデルの実装とRepositoryの実装は一緒に考える必要はない
  • Repositoryに限らず、インターフェースを切ってポート(ポートアダプターのポート)になっている箇所は、外部からきた情報を内部で使いやすい形に変換する役割がある。
    • なので、モデルの実装とRepositoryの実装は分けて考えることができる

複数コンテキストの結合を緩めるというのはどういうことか?

image.png (61.7 kB)
  • 別コンテキストと同じ形のEntityを使うと、取得元のコンテキストが変更になると、こちらのEntiryも書き換える必要がある場合もあるかもしれない
  • ここでは 必要な情報だけをもつ値オブジェクトとして定義している

値オブジェクトに不変性がないテストってどんな感じに書くの?

  • 4ページの最後に「コピーコンストラクタを使用して、値オブジェクトに不変性がないテストを書く」とあるが、具体的にどういうテストの内容になるの?
    • コピーコンストラクタがいまいちわかってないかも

  • Unitテストで、コピーしたオブジェクトとadd(なんか金額計算とか)などした後のオリジナルのオブジェクトを比較して、値が変わってないことをテストするとか?
  • コピーコンストラクタでオブジェクトを2つ用意し、副作用のないメソッドを実行し値が変わっていないことをテストする(IDDD本)
    • 値オブジェクトをテストする際に不変であることを確かめたい。
  • 「値オブジェクトに不変性がないテストを書く」じゃなくて、「値オブジェクトが不変である」ことをテストする

値オブジェクトの特徴に等価性ってあるけど、「等価性」の判定方法を提供するようなコードって毎回実装する必要がある?

  • 例えばequalsメソッドを毎回オーバーライドする必要があるの?必要になったらでいいよね?

  • PHPとかだったら、equalsメソッドないからいいかもしれないけど、C#とかだったら最初からequalsメソッドがあるからオーバーライドしておかないといけない。
    • 使うひとが、equalsメソッド使っちゃうかもしれないし。

phpでも列挙型を積極的に使って良し?

次回

【ミライトデザイン社内勉強会#16】「IDDD本から理解するドメイン駆動設計」輪読会~第7章「ドメインサービス」~ - Qiita

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?