Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

実践DDD本の第5章「エンティティ」 ~一意な識別子で同一性を識別~

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加

 ドメイン駆動設計(DDD)は、顧客と開発者が業務を戦略的に理解し、共通の言葉を用いてシステムを発展させていく設計手法です。前回はDDDのアーキテクチャについて紹介しました。5回目となる今回は、「エンティティ」に対するモデリングの流れを通して、一意な識別子やコーディング例について紹介します。

目次

エンティティと値オブジェクト

 DDDにおける「エンティティ」とは一意なものを表現する概念です。一意であるため、長期にわたって変化できるオブジェクトとなります。例えば「社員」というエンティティの場合、社員番号で社員を一意に識別することで、同じ人物であることを把握し、住所や所属といった属性を適切に変更できます。なお、一意に識別して変更を管理する必要がないものは「値オブジェクト(6章にて紹介)」として取り扱います。

エンティティと値オブジェクト
エンティティと値オブジェクト

DDDでよくある失敗

 DDDで設計を始めてみると、データの格納方法ばかり気になってしまうことがよくあります。このようなERモデリング(テーブル構成とリレーション関係)を先に検討されたエンティティは、DB項目のプロパティしか存在しない機能不足なモデル「ドメインモデル貧血症」になりがちです。ドメインモデル貧血症とは、オブジェクト指向設計の基本である「データと処理を一緒に取り扱う」ことを行わない、単なる手続き型設計のことです。一見、ドメインモデルと同じような構造を持ちつつも、オブジェクトの「振る舞い」が不足している状態を指します。

 そのため、DDDで設計する場合には、DOA(データ中心アプローチ)のようにデータ中心で検討するのではなく、OOA(オブジェクト指向アプローチ)のような振る舞いも含めたモデルから検討する方法が適しています。

 また、エンティティは「オブジェクトの区別が必須」であるケースにおいて使用する概念です。しかし実際には、値オブジェクトで十分なものをエンティティとして設計してしまう失敗があります(もし、エンティティが多数を占める単純なCRUDシステムであれば、DDDの採用自体が間違っている可能性もあります。このような場合にはDDDを採用せず、普通に開発したほうがよいでしょう)。

モデリングとエンティティ発見の流れ

 先ほど述べたようにDDDでの設計は(DB設計ではなく)オブジェクトモデリングを中心に進めていきます。エンティティの発見と検討の流れは次の通りです。

  • [1]ソフトウェア要件の理解
  • [2]モデリングを検討しエンティティを抽出
  • [3]エンティティを識別する属性と振る舞いを検討
  • [4]「一意な識別子」の設計
    • 一意な識別子の生成方法
    • 一意な識別子の生成タイミング
  • [5]エンティティの振る舞い(メソッド)を検討
  • [6]エンティティの作成方法(コンストラクタ/ファクトリ)を検討
  • [7]エンティティのバリデーションを検討

 IDDD本では、SaaSOvationのサンプルを用いて「認証・アクセスコンテキスト」の「ユーザー」や「テナント」に対してモデリングと実装(JavaC#)を検討しています。それでは順に見ていきましょう。

[1]ソフトウェア要件の理解

 設計を始めるにあたり、まず業務内容から整理していきます。開発する対象業務について、ドメインエキスパートから要望を聞き出していきます。ここでは業務仕様を「簡単なソフトウェア要件」という形で書き出しています(難易度によりますが、「ユースケース」や「ユーザーストーリー」といった成果物を作成し、要件の明確化を行ってもよいでしょう)。

ソフトウェア要件の理解
ソフトウェア要件の理解

[2]モデリングを検討しエンティティを抽出

 次に、チームで共通のユビキタス言語を構築することを意識して、ドメインエキスパートと十分な議論を行います。なお、ユビキタス言語を見つける流れについては、第1章の説明もご確認いただければと思います。

要件を整理しエンティティを検討
要件を整理しエンティティを検討

エンティティの検討

 エンティティの抽出においては、シナリオにおいて「変更」というキーワードがある箇所に注目します。主語の用語がエンティティとなる可能性が高くなります。SaaSOvationでは「テナント」と「ユーザー」をエンティティの候補として選択しています。

[コラム]DDD本におけるエンティティの解説

 IDDD本では、エンティティの解説として、エヴァンス氏の次の説明を引用しています。

 あるオブジェクトが属性ではなく同一性によって識別されるのであれば、モデルでこのオブジェクトを定義する際には、その同一性を第一とすること。クラスの定義をシンプルに保ち、ライフサイクルの連続性と同一性に集中すること。形式や履歴に関係なく、各オブジェクトを識別する手段を提供すること。…(中略)…モデルは、同じものであるということが何を意味するかを定義しなければいけない。

 属性やふるまいに集中するよりは、エンティティオブジェクトの定義を、最も本質的な特徴にまでそぎ落とすこと。特にエンティティを識別するものや、それを検索し突き合わせるのに通常使用されるものが、そういう本質的な特徴だ。つけ加えるのはその概念にとって本質的なふるまいと、そのふるまいが必要とする属性だけにすること。

 モデリングをしていると細かい属性と振る舞いに気を取られがちですが、エヴァンス氏の言葉にあるように、エンティティの同一性に注目しシンプルに保つことが重要だと思われます。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 青木 淳夫 (株式会社ネクストスケープ)(アオキ アツオ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2017年5月時点での登録メンバは52名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂き...

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

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

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

もっと読む

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5