SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

IDDD本から理解するドメイン駆動設計

実践DDD本 第6章「値オブジェクト」~振る舞いを持つ不変オブジェクト~

IDDD本から理解するドメイン駆動設計 第6回

  • X ポスト
  • このエントリーをはてなブックマークに追加

値オブジェクトの実装コード

 最後に、値オブジェクトの実装について見ていきましょう。ここではアジャイルプロジェクト管理コンテキストで、ビジネス的な価値を計算する「ビジネス優先度(BusinessPriority)」に関する実装(JavaC#)を見ていきます。

BusinessPriorityに関する値オブジェクト群
BusinessPriorityに関する値オブジェクト群

 値オブジェクトである「ビジネス優先度」は、エンティティ「バックログアイテム」の属性の一部です。「ビジネス優先度」はビジネス優先度レーティングの属性を保持し、ビジネス優先度合計を使用して各種計算を行います。

BusinessPriorityTotalsクラス(値オブジェクト)の実装

 BusinessPriorityクラスのメソッドで使用される「BusinessPriorityTotals」の実装から見ていきましょう。これはビジネス優先度の合計値を格納する値オブジェクトで、全てのバックログアイテムに関するコストやリスクの総計を格納します。BusinessPriorityクラスにて、他のバックログアイテムと比較したり、パーセンテージを計算したりするために使用されます。

BusinessPriorityTotals「値オブジェクト」の実装例(C#)
BusinessPriorityTotals「値オブジェクト」の実装例(C#)

 これまで紹介してきた通り、コンストラクタで全ての属性値を設定でき、外部から変更できるSetterが存在しないことがかります。これによ、値オブジェクトの条件である「不変性」を満たしています。

 また、値オブジェクトのインスタンスが等しいかどうかを判断する「等価性」の判定を属性値が全て同じかどうかで判断するため、GetEqualityComponentsメソッドをオーバーライドして、全ての属性の値を返しています。親クラスであるValueObjectにてEqualsメソッド等の共通処理が実装されているので、これによって等価判定が可能となります。

BusinessPriorityRatingsクラス(値オブジェクト)の実装

 次に「BusinessPriorityTotals」の実装を見てみましょう。このクラスはビジネス優先度の合計値を格納する値オブジェクトです。特定のプロダクトバックログアイテムを実装するに、どの程度の事業価値と出費があるかを表現しています。

BusinessPriorityRatings「値オブジェクト」の実装例(C#)
BusinessPriorityRatings「値オブジェクト」の実装例(C#)

 先ほどの「BusinessPriorityTotals」クラスとの違いはコンストラクタにバリデーションチェックが入っていることでしょう。各引数(ベネフィット、ペナルティ、コスト、リスク)の値が1〜9以外であればエラーとなるようにアサーションを宣言しています。バリデーションについては、第5回のエンティティの記事にて紹介していので、詳細はそちらをご覧ください。

属性を変更した値を戻すWith〜メソッド

 値オブジェクトは不変であることを前提としていますが、交換可能性の部分で紹介したように、特定の属性の値を変更した新しいオブジェクトを生成することが可能です。このクラスではWithから始まるメソッドで既存の値をコピーした新しいインスタンスを生成しています。例えば「WithAdjustedCost(int cost)」メソッドの場合、引数で受け取ったコストの値のみ変更しています。既存の値を使用してコンストラクタを呼び出すことで、一部の値のみ変更したオブジェクトを生成しています。

BusinessPriorityクラス(値オブジェクト)の実装

 最後に、BusinessPriorityクラスを見てみましょう。このクラスではビジネスプライオリティのビジネスロジックを計算しています。

BusinessPriority「値オブジェクト」の実装例(C#)
BusinessPriority「値オブジェクト」の実装例(C#)

 このクラスでは、ビジネスロジックに応じた計算を行っています。各メソッドでは、自分自身の属性と引数の値を使って計算していることがわかります。Setterはなく、不変で、副作用がないこともわかると思います。

プライマリコンストラクタとコピーコンストラクタ

 なお、BusinessPriorityクラスには2種類のコンストラクタが存在しています。一つは「プライマリコンストラクタ」で、これまで登場している普通のコンストラクタです。「public BusinessPriority(BusinessPriorityRatings ratings)」の部分では、ビジネスプライオリティレーティングを引数として受け取り、新しいオブジェクトを生成しています。

 これに対して「public BusinessPriority(BusinessPriority businessPriority)」が「コピーコンストラクタ」となります。このコンストラクタでは自分自身を引数として受け取ります。このようなコピーコンストラクタは、値オブジェクトに不変性がないテストを書くときにく使用されます。なお、値オブジェクトのテストでは、ドメインエキスパートとビジネス的な話をして、その仕様を満たすようにテストコードを記載するように努めます。

最後に

 以上、本記事ではDDDの値オブジェクトについて紹介しました。値オブジェクトの概要を理解し、エンティティや標準型との違いや実装方法について学べたかと思います。DDDでは「優先度」や「電話番号」といったユビキタス言語をプリミティブな数値型で済ませてしまうのではなく「値オブジェクト」として表現することを理解できたと思います。次の第7回ではDDDの「サービス」について紹介します。

参考資料

 

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
IDDD本から理解するドメイン駆動設計連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 青木 淳夫(アオキ アツオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10184 2017/06/02 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング