AdventureWorksをモデリングしてDDDしながらドメインモデルで実装してみる(6)

分析モデルを安定化させ設計モデルに整理する

ビジネスルールを記述するためにエンティティの機能定義を行ったので、次は実際に実行可能な設計モデルに整理します。ここではビジネスオブジェクトをどのように実装するかを考えていきます。
実装の観点としては、低結合・高凝集やSRP(1クラス・1責務)を頭において、変更に強い安定した構造に整理して構築します。方向としては概念エンティティの構造を分析してより小さな責務をもつクラスに分解・整理することを考えます。慣れてくると案外見えてくるかもしれませんが、なかなか直ぐには難しいかもしれません。
ビジネスオブジェクトを対象とする場合もう少し便利な方法があります。RDBの世界でよく利用される関数従属性や、ライフサイクルの違いで判断する方法です。前者は特に説明は必要がないと思いますが、後者は同じライフサイクルを持つデータは同じグループの可能性が高いという考え方です。多くの場合 1つのクラスに多くの責務がある状態から責務を分解して複数クラスを割り当てていきますので、関数従属性やライフサイクルの観点でクラスのプロパティをグループ化して切り出して新しいクラスを識別します。

クラスの責務を分解して整理する

従業員のカラムを見てみると「VacationHours,SickLeaveHours」の変更頻度は休暇を消化したタイミングなので他のカラムとかなり違いがあります。これらを従業員(Employee)から切り出して「休暇」とします。
さらに、従業員のライフサイクルの観点で考えた場合、「CurrentFlag」の意味は重要で在職かどうかを表しています。単なるフラグ情報というよりもデータ全体の状態を表していますので、明示的に状態として取り扱います。「MaritalStatus」も婚約状態を表していますので状態のように見えますが、現時点ではこちらは逆に単なる情報として取り扱います。
あと、「Title」は別エンティティとしても良いものですので、エンティティ候補として別出しします。基本的に区分やフラグ類は、元のエンティティを分類・説明するか、エンティティの状態を表していることが多く、このような場合は外だしして責務を分離可能にします。

基本的にはクラスが細かくなることを恐れず、1クラス・1責務にするぐらいのつもりで分離することがお勧めです。ただし、必要以上に時間をかけることは避けてください。単なる画面の表示するための情報にすぎないデータ群を構造化しても時間がかかる割には得られるメリットは余りありません。*1。分析マヒにならない。 YAGNI(今必要のあることだけをやれ)の考え方も頭に入れておきましょう。

*1:そもそも対象領域が柔らかく構造化が難しい場合もあります。このような場合に無理やり構造化を試みると時間をかなり消費してしまいます。柔らかいものをそのまま柔らかいまま取り扱うことも必要になります