2010-05-18 5 views
67

나는 빈혈 도메인 모델을 이해하려고 시도하고 있으며, 왜 그들이 안티 패턴일까요?빈혈 영역 모델 회피 - 실제 사례

실제 세계의 예입니다. 이름, 성별, 이름, 등

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

다음으로는 '리드로 알려진 걸려 오는 전화와 웹 사이트 문의 (회전 포함하는 시스템을 가지고 -

나는 특성의 톤을 가진 Employee 클래스를 가지고 ')를 판매 직원들 사이에 고르게 제공합니다. 이 시스템은 라운드 로빈 문의, 휴일, 직원 선호도 확인 등을 포함하여 매우 복잡합니다. 따라서이 시스템은 현재 서비스로 분리되어 있습니다 : EmployeeLeadRotationService.

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

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

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

난 정말이 방법에 많은 문제가 발생하지 않지만, 아마도 이것이 내가 실행해야 뭔가 :

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 
    } 
} 

은 다음 웹 사이트 문의 양식의 뒷면에 우리는이 같은 코드를 비명지기 때문에 빈혈 도메인 모델입니다.

하지만 리드 회전 서비스의 논리가 어디로 가야하는지 명확하지 않습니다. 선두에 있어야합니까? 직원에게 들어가야합니까?

로테이션 서비스에 필요한 모든 주입 리포지토리는 무엇인가? 직원을 대할 때 대다수의 리포지토리가 필요하지 않으므로 대부분 직원에게 주입되는 방법은 무엇입니까?

+0

+1 큰 질문입니다. – mdma

+0

그렇다면 .SelectEmployee()를 넣는 것이 명확하지 않으면 'ILead'모양이 어떻게 될까요? –

+0

이 경우 리드는 웹 문의이므로 댓글 속성 등을 갖습니다.하지만 전화 문의, 응용 프로그램, 따옴표 등은 모두 약간 다릅니다. ILead 인터페이스는 LocationOfLead, TimeOfLead 등의 속성을가집니다. – cbp

답변

49

이 경우 빈혈 도메인 모델을 구성하지 않습니다. 빈혈 도메인 모델은 specifically about validating and transforming the objects입니다. 따라서 외부 함수가 실제로 Employee의 상태를 변경하거나 세부 정보를 업데이트 한 경우이 예가 될 수 있습니다.

이 경우 어떤 일이 일어나고 있는지는 직원의 모든 정보를 바탕으로 모든 직원을 선택하고 그 중 하나를 선택하는 것입니다. 다른 사람들을 검사하고 발견 한 것과 관련하여 결정을 내리는 별도의 물건을 갖는 것은 좋습니다. 하나의 상태에서 다른 상태로 객체를 전환하는 데 사용되는 객체를 갖는 것은 좋지 않습니다.

귀하의 경우 빈혈 도메인 모델의 예는 직원 오브젝트를하고 시간이 플래그는 경우에 생긴 것을 확인하고, 주를 위해 일 업데이트하는 외부 방법

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

을 가지고하는 것입니다 시간이 특정 한도를 초과합니다. 이 문제는 Employee 객체 만있는 경우 정확한 제약 조건 내에서 시간을 수정하는 방법에 대한 지식이 없다는 것입니다.이 경우이를 처리하는 방법은 updateHours 메소드를 Employee 클래스로 이동하는 것입니다. 이것이 빈혈 도메인 모델의 핵심 패턴입니다.

+0

그러나 Employee가 데이터베이스의 영구 객체 인 경우 어떻게됩니까? 왜 거기에 방법을 넣어야합니까? 같은 질문은 내부에 메서드를 넣지 않는 DTO의 경우 유효합니다. 어디서 updateHours 메서드를 넣을까요? – Pascal

+0

'updateHours'는 Employee 클래스에 속해 있습니다. 완료된 작업과 같이 시간을 업데이트하는 데 필요한 데이터를 전달해야합니다. 공동 작업자 개체도 좋지만 서비스가없는 것이 좋습니다. – MauganRa

29

디자인이 좋다고 생각합니다. 알다시피, 빈혈 도메인 모델의 안티 패턴은 도메인 객체로 코딩 된 동작을 피하는 경향에 대한 반발입니다. 그러나 반대로 그것은 을 의미하지 않습니다. 도메인 객체와 관련된 동작은 해당 객체에 의해 캡슐화되어야합니다.

일반적으로 도메인 개체에 본질적으로 묶여 있고 해당 도메인 개체 인스턴스로 완전히 정의 된 동작은 도메인 개체에 포함될 수 있습니다. 그렇지 않으면 책임을 분명히하기 위해, 당신이 한 것처럼 공동 작업자/서비스에 외부 적으로 배치하는 것이 가장 좋습니다.

+5

. 이것은 내부 로직이 많은 외부 모듈 (LeadQueueManager 또는 기타)입니다. 이것은 빈혈 도메인 모델이 아닙니다. 직원이 통화 대기열 예약에 대해 무엇을 알고 있습니까? Nothing;) – TomTom

13

모두 머리 속에 있습니다. 회전 서비스가 도메인 모델의 일부로 간주되고 문제가 해결됩니다.

회전은 많은 직원에 대한 정보를 유지해야하므로 리드 나 단일 직원 개체에 속하지 않습니다. 그것은 그 자체로 도메인 객체가되어야합니다.

"RotationService"의 이름을 "Organization.UserSupportDepartment"와 같은 것으로 바꾸면됩니다.

0

도메인 모델에 동작이 아닌 역할 및 사물 만 포함되어있는 경우 빈혈이납니다. 그러나 나는 모델이 아닌 개체 인과 관련된 동작에 대해 이야기하고 있습니다. 나는 당신의 질문에서 https://stackoverflow.com/a/31780937/116442

, 당신은 내 첫 번째 두 개의 도메인 분석 모델링 규칙을 깰 ... 다른 답변에서 그들 사이의 차이 이야기 - (녹음) 활동으로 모델링

  1. 행동은 마음에있다 도메인 모델의 먼저 추가하십시오.
  2. 도메인 활동을 메소드가 아니라 클래스로 모델링하십시오.

"문의"라는 활동이 모델에 추가됩니다. 이 모델에는 동작이 있으며 외부 컨트롤러 또는 스크립트없이 개체 그룹으로 결합하여 작업 할 수 있습니다.

EnquiryHandlerModel