빈혈 도메인 모델 및 도메인 서비스 주입


19

빈혈 도메인 모델은 마틴 파울러 도메인 중심의 디자인에서 안티 패턴으로 설명되어 있습니다. 도메인 모델에 대한 비즈니스 로직을 갖기 위해 종종 도메인 서비스가 사용됩니다. 그러나 도메인 서비스에 도메인 서비스를 주입하는 것은 Vaughn Vernon에 의해 해로운 것으로 간주됩니다 ( "도메인 기반 디자인 구현, 페이지 387"참조).

내 의견으로는, 그 의견은 모순입니다, 이것이 사실입니까? 두 점을 어떻게 고려할 수 있습니까?

그것은 정말 도메인 서비스와 풍부한 도메인 모델 주입빈혈 도메인 모델 및 일반 도메인 서비스 ?


4
나는 이것에 대해 결코 전문가는 아니지만 도메인 서비스와 도메인 엔터티에 들어가는 논리 유형 이 근본적으로 다르다고 생각했습니다. 엔터티로 들어가는 논리는 개체를 올바른 상태로 유지하는 데 필요한 논리입니다. 여기에는 검증 및 변환 논리가 포함됩니다. 반면 도메인 서비스는 더 높은 수준의 논리를위한 것입니다. 예를 들어 도메인 서비스는 여러 유형의 엔터티를 포함하는 비즈니스 프로세스를 모델링하는 것이 복잡한 방법입니다.
MetaFight

2
@MetaFight : 비즈니스 프로세스가 복잡한 방식으로 여러 엔터티에 영향을 주더라도 우수한 집계 루트 도메인 모델, 즉 영향을받는 모든 엔터티에 속성 또는 필드로 액세스 할 수있는 도메인 모델이 제공되므로 서비스 없이도이를 달성 할 수 있습니다.
Greg Burghardt

그 의미가 :)
MetaFight

답변:


16

빈혈 모델은 단순히 데이터 컨테이너입니다. 동작이 포함되어 있지 않습니다. (이것은 실제로 기능적 패러다임에서 좋은 것으로 간주 될 수 있습니다.) 빈혈 모델의 반대 는 도메인 서비스로 가득 찬 모델이 아닙니다 . 두 가지 극단을 설명하고 있습니다. 둘 다 나쁩니다.

빈혈 모델이있는 경우 OOP가 제공하는 것을 완전히 수용하지 않은 것입니다. 해당 모델에 서비스를 주입하기 시작하면 해당 모델에 속하지 않는 우려 사항이 주입 될 수 있습니다. 그 또는 당신의 모델은 생각보다 빈혈입니다. 필요하지만 누락 된 것을 제공하는 것 이외의 다른 서비스가 필요한 이유는 무엇입니까? (실종은 빈혈을 의미 할 수 있습니다.)

두 "텔레"를 피하면 디자인이 더 강력 해집니다. 모델에 필요한 서비스가 있습니까? 모델로 이동해야 할 수도 있습니다. 그렇지 않은 경우 우려 사항을 재고해야합니다. 모델의 행동은 작동합니다 내부 모델. 그것은 주로 회원들에게 관심을 가져야한다. 하지만 기억, 아직도 그 작업 일이있을 것이다 모델. 예를 들어, 모델이 어떻게 든 관련되어 있어도 TCP 연결을 열거 나 UI 이벤트를 수신해서는 안됩니다. 그것은 다른 사람의 책임이며 누군가가 절대 모델 내부에 속하지 않는다는 것 입니다.


7
내가 기억하고 싶은 좋은 점은 도메인 모델이 비즈니스 로직을 구현 하고 도메인 서비스 가 도메인 모델에서 비즈니스 로직을 실행 한다는 것입니다. 차이점은 누가 누가 전화하는지입니다. 서비스는 도메인 모델 메소드를 호출 할 수 있습니다. 도메인 모델이 서비스 메소드를 호출하는 경우 패턴을 헤드 위로 뒤집 었습니다.
Greg Burghardt

7

모순되지 않습니다. 두 제안자는 실제 코드를 도메인 객체 자체에 넣기를 원합니다.

즉.

public class Order
{
    private string status = "not bought";
    public void Buy()
    {
        this.status = "bought";
    }
}

vs ADM

public class Order
{
    public string Status = "not bought";
}

public class BuyingService
{
    public Order Buy(Order order)
    {
         Order o = new Order();
         o.status = "bought";
         return o;
    }
}

주사 서비스 대

public class Order
{
    public Order(IBuyingService bs)
    {
        _bs = bs;
    }
    private IbuyingService _bs;
    private string status = "not bought";
    public void Buy()
    {
        this.status = _bs.Buy();
    }
}

public class BuyingService : IBuyingService
{
    public string Buy()
    {
         return = "bought";
    }
}

솔직히 각 접근 방식에는 장점과 단점이 있습니다. 당신이 선택한 것은 주로 개인적인 취향의 문제입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.