質問

私は、貧血ドメインモデルと、おそらくアンチパターンである理由を理解しようとしています。

これが現実世界の例です。

私は従業員クラスを持っています。このクラスには、名前、性別、ユーザー名など、たくさんのプロパティがあります。

public class Employee
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public string Username { get; set; }
    // Etc.. mostly getters and setters
}

次に、販売スタッフの間で、着信の電話とウェブサイトの問い合わせ(「リード」として知られている)を均等に回転させることを伴うシステムがあります。このシステムは、ラウンドロービングの問い合わせ、休日、従業員の好みなどをチェックすることを含むため、非常に複雑です。そのため、このシステムは現在、サービスに分類されています。

public class EmployeeLeadRotationService : IEmployeeLeadRotationService
{
     private IEmployeeRepository _employeeRepository;
     // ...plus lots of other injected repositories and services

     public void SelectEmployee(ILead lead)
     {
         // Etc. lots of complex logic
     }
}

次に、ウェブサイトの問い合わせフォームの裏側に、次のようなコードがあります。

public void SubmitForm()
{
    var lead = CreateLeadFromFormInput();

    var selectedEmployee = Kernel.Get<IEmployeeLeadRotationService>()
                                 .SelectEmployee(lead);

    Response.Write(employee.Name + " will handle your enquiry. Thanks.");
}

私はこのアプローチで実際に多くの問題に遭遇しませんが、おそらくこれは私が叫ぶべきものだと思われます。 貧血ドメインモデル.

しかし、私にとっては、リードローテーションサービスのロジックがどこに行くのかは明確ではありません。それはリードするべきですか?従業員に行くべきですか?

ローテーションサービスが必要とするすべての注入されたリポジトリなどについてはどうですか?従業員を扱うときにほとんどの場合、これらのリポジトリのいずれも必要としないことを考えると、従業員にどのように注入されますか?

役に立ちましたか?

解決

この場合、これは貧血ドメインモデルを構成しません。貧血ドメインモデルはです 具体的には、オブジェクトの検証と変換について. 。したがって、この例は、外部関数が実際に従業員の状態を変更するか、詳細を更新した場合です。

この場合に起こっていることは、あなたがすべての従業員を連れて行き、彼らの情報に基づいてそのうちの1つを選択していることです。他の人を調べ、それが見つけたものに関して決定を下す別のオブジェクトを持っていることは問題ありません。ある状態から別の状態にオブジェクトを遷移するために使用されるオブジェクトを持っていることは問題ありません。

あなたの場合の貧血ドメインモデルの例は、外部方法を持つことです

updateHours(Employee emp) // updates the working hours for the employee

これにより、従業員のオブジェクトが必要になり、1週間の労働時間を更新し、時間が一定の制限を超えた場合にフラグが上がっていることを確認します。これに関する問題は、従業員のオブジェクトのみを持っている場合、正しい制約内で時間を変更する方法についての知識がないことです。この場合、それに対処する方法は、UpdateHoursメソッドを従業員クラスに移動することです。それは、貧血ドメインモデルアンチパターンの核心です。

他のヒント

ここであなたのデザインは大丈夫だと思います。ご存知のように、貧血ドメインモデルアンチパターンは、ドメインオブジェクトでコーディングされた動作を回避する傾向に対する反発です。しかし、逆にそれは意味しません すべて ドメインオブジェクトに関連する動作は、そのオブジェクトによってカプセル化される必要があります。

経験則として、本質的にドメインオブジェクトに結び付けられ、1つのドメインオブジェクトインスタンスがドメインオブジェクトに含めることができるという観点から完全に定義されている動作。そうでなければ、責任を明確にするために、あなたがしたように、それを協力者/サービスに外部から置くことをお勧めします。

それはすべてあなたの頭の中にあります - ローテーションサービスはドメインモデルの一部であると考え、問題は解消します。

ローテーションは、多くの従業員に関する情報を保持する必要があるため、リードも単一の従業員オブジェクトにも属します。それ自体がドメインオブジェクトに値するに値する。

「RotationService」を「組織」のようなものに変更するだけで、それが明らかになります。

ドメインモデルには、動作としてのアクティビティではなく、役割や物のみが含まれている場合、それは貧血です。しかし、私は行動について話している モデル ではありません 物体. 。私は別の答えでそれらの違いについて話します... https://stackoverflow.com/a/31780937/116442

あなたの質問から、あなたは私の最初の2つのドメイン分析モデリングルールを破ります: -

  1. (記録された)アクティビティとしてモデル化された動作は、ドメインモデルの中心にあります。最初に追加します。
  2. メソッドではなく、クラスとしてモデルドメインアクティビティ。

モデルにアクティビティ「問い合わせ」を追加します。これにより、モデルには動作があり、外部コントローラーまたはスクリプトなしでオブジェクトのグループとして組み合わせて機能することができます。

EnquiryHandlerModel

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top