プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • DDD
  • 【DDD】「ValueObject(バリューオブジェクト)」、作成判断など
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【DDD】「ValueObject(バリューオブジェクト)」、作成判断など

08.21

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

特徴

値として扱うクラス

DB項目を扱う。

ただ、項目に対してビジネスロジックがない場合は基本データ型でも良い。

別インスタンスでも値が同じなら同じものと判断する。

普通のクラスと違って扱いはインスタンスというよりは値に着目する。別インスタンスでも値が同じなら同じものとみなす。

具体的な実装

普通にインスタンス同士を比較しても一致しないので比較メソッド(JavaやC#で言えば、Equalsメソッド)をオーバーライドしてそれを値が同じならtureを返すようにいじる。(なお、nullチェックはすること。値がnullだったら「false:インスタンスが一致しない」を返す。後、「==」や「!=」メソッド(staticメソッド)についてもケアすること。)

ただ、これを全てのValueObjectに対して記述していくのはめんどくさいと思うので抽象クラス(Abstract)として基底クラスを作って共通化するようにしましょう。「ValueObject」というクラスを別途作って継承させます。

なお、比較対象の

不変にする。(絶対に「完全コンストラクタパターン」(readonlyなクラス)とする。)

コンストラクタで初期化するタイミングだけが値がセットされて2度と変わらない。もし、値を変えたくなった場合は別インスタンスで生成し直す作りにします。readonlyなので、セッターは作ってはいけません。

なぜか?

これはイミュータブルであることによってバグが混在されにくくなるためです。並行、並列処理などを使う場合などはそれが顕著になりますが、不変なオブジェクトになっていることによって安心して扱うことができます。ただ、デメリットとしてインスタンスを使いまわせないのでパフォーマンスに影響が出る可能性がある点です。ただ、バグが混入する可能性を減らす方が良いでしょう。

フィールドを更新するメソッドを作ったときはどうするか?

例えば、名前クラスで命名変更メソッドみたいなものを作ったとして場合はそのまま書くとフィールドを変更することになってしまいます。そうしないために新しく別の値を設定して初期化したもので自分自身のオブジェクトをnewして新しいインスタンスとして返却するようにします。

値とロジックを一体化させる。

継承はさせない。

メリット

  • 基本データ型で値を定義する場合に比べてロジックが散らばりにくい。
  • 基本データ型で値を定義する場合に比べてバグが発生しにくい。

ValueObjectの作成判断

ではこういう場合はどうでしょうか?

1
FullNameクラスがあって、FirstNameとLastNameをバリューオブジェクト化するかどうか。

ここまで細かい粒度までクラス化していたらさすがにやりすぎと思う部分もあるかもしれません。

判断基準

では、判断基準としては下記が良いでしょう。

  • ルールが存在しているか
  • それ単体で取り扱いたいか。

ルール

例えば、FirstNameやLastNameだけの独自ルールがあるかどうかなどで判断します。

それ単体で取り扱いたいか

例えば、FirstNameやLastNameを単体でシステム上取り扱うケースはあるかどうかなどです。

代替案

仮にオブジェクト化しなかったとしても、コンストラクタ内でチェックすることは可能です。

ValueObjectの作成タイミング

DBなどから値を取得したらなるべく早く作成するのが吉です。

区分のValueObject

区分(例えば、0:晴れ、1:曇り、2:雨など)は少し特殊です。

メンバ

区分値(固定値)

staticなメンバとして自身のValueObjectをnewして持たせます。(2度と変わらない。)

なお、区分ごとに一つのメンバにします。(例えば、晴れならSunny変数、曇りならCloud変数など)

こうすることで外部から使う時も別に固定値ファイルとかを作らずにクラスからそのままメンバを参照できます。(もちろんクラス内部からも直接参照できます。)

選択値(可変値)

インスタンス変数として選択値を持たせます。場合によっては区分値(固定値)と比較する処理などを作ったりもします。

スポンサーリンク
  • 2021 08.21
  • miyabisan2
  • コメントを書く
  • DDD
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2021 09.23

    【DDD】「コンテキストマップ」について

  2. 2021 09.19

    【DDD】「コマンドオブジェクト」を作る。

  3. 2021 09.24

    【DDD】フロントエンド に「クリーンアーキテクチャ」を適用した場合、Reduxのデザインパターン

  4. 2021 09.20

    【DDD】「ドメイン」、「境界付けられたコンテキスト」

  5. 2021 09.12

    【DDD】「CQRS」の活用

  6. 2021 08.21

    【DDD】「Entity(エンティティ)」、結合エンティティ、バリューオブジェクト、仕様オブジェクトとの作成判断基準

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【DDD】「Entity(エンティティ)」、結合エンテ…

【オブジェクト指向】「SOLIDの原則」の概要

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー