anemic-domain-model - icf - iron deficiency中文




避免貧血域模型-一個真實的例子 (3)

我試圖了解貧血域模型,以及為什麼它們被認為是反模式。

這是一個真實世界的例子。

我有一個Employee類,它有很多屬性 - 名稱,性別,用戶名等

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

接下來,我們建立了一個系統,讓銷售人員均勻地調用來電和網站查詢(稱為“潛在客戶”)。 這個系統是相當複雜的,因為它涉及到循環查詢,檢查假期,員工偏好等等。所以這個系統目前被分成服務:EmployeeLeadRotationService。

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.");
}

我並沒有真正遇到這種方法的許多問題,但據說這是我應該從尖叫的東西,因為它是一個貧血的領域模型

但對我而言,並不清楚領導輪換服務的邏輯應該放在哪裡。 它應該領先嗎? 它應該進入員工嗎?

輪換服務需要的所有註入的倉庫等等 - 他們將如何注入員工,考慮到與員工打交道的大部分時間我們不需要任何這些倉庫?


在這種情況下,這不構成貧血區域模型。 貧血領域模型專門用於驗證和轉換對象 。 所以一個例子是如果一個外部函數實際改變了員工的狀態或者更新了他們的詳細信息。

在這種情況下發生的事情是,你要帶走所有的員工,並根據他們的信息選擇其中的一員。 擁有一個單獨的對象來檢查其他對象並就其所發現的事物做出決定是很好的。 有一個對像用於將對像從一個狀態轉換到另一個狀態是不好的。

在你的案例中的一個貧血域模型的例子是有一個外部方法

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

它接收一個Employee對象並更新本週工作的小時數,確保在小時數超過一定限制時提升標誌。 這個問題是,如果你只有Employee對象,那麼你不知道如何在正確的約束內修改他們的小時。 在這種情況下,處理它的方法是將updateHours方法移入Employee類。 這是貧血域模式反模式的關鍵。


如果你的領域模型只包含角色和事物,而不是行為作為行為,那麼它是貧乏的。 但是,我在談論關於模型而不是對象的行為 。 我在另一個答案中談論他們之間的區別... https://.com/a/31780937/116442

從你的問題,你打破了我的前兩個領域分析建模規則: -

  1. 行為建模為(記錄)活動是領域模型的核心。 首先添加它們。
  2. 模型域活動作為類,而不是方法。

我會添加一個活動“調查”模型。 有了它,模型就具有行為,並且可以組合併作為對象組工作,而無需外部控制器或腳本。


這一切都在你的腦海中 - 考慮輪換服務成為領域模型的一部分,問題就會消失。

輪換需要保留關於許多員工的信息,因此它既不屬於潛在客戶,也不屬於任何單個員工對象。 它確實值得自己成為一個域對象。

只需將“RotationService”重命名為“Organization.UserSupportDepartment”即可。