2009-07-29 2 views
3

에서 나를 구원 나는 일반적으로 비즈니스 개체에서이 같은 사례를 본 적이 :비즈니스 오브젝트

public void Save() 
{ 
    if(this.id > 0) 
    { 
      ThingyRepository.UpdateThingy(this); 
    } 
    else 
    { 
      int id = 0; 
      ThingyRepository.AddThingy(this, out id); 
      this.id = id; 
    } 
} 

왜 여기에 비즈니스 오브젝트에? 이것은 비즈니스 논리보다는 문맥 또는 데이터와 관련이 있습니다.

예를 들어, 같은 것을 통해 갈 수있는 객체의 소비자 ...

...Get form values from a web app... 

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value); 
thingy.Save(); 

또는 갱신이 같은 ...

... Get form values from a web app... 

Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value)); 
Thingy.Name = Form["name"].Value; 
Thingy.Save(); 

은 왜이다 ? 왜 계산, 비즈니스 특정 규칙 등과 같은 실제 비즈니스 로직을 포함하지 않고 검색/지속성을 피할 수 있습니까?

이 방법을 사용하여, 코드는 다음과 같습니다

... Get form values from a web app... 

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value); 
ThingyRepository.AddThingy(ref thingy, out id); 

또는 갱신이 같은 ... 이러한 예, 소비자, 모두에서

... get form values from a web app ... 

Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value)); 
thingy.Name = Form["Name"].Value; 
ThingyRepository.UpdateThingy(ref thingy); 

사람 오브젝트에 대해 수행중인 작업을 가장 잘 알고 있으며 저장소를 호출하고 ADD 또는 UPDATE를 요청합니다. 객체는 그 컨텍스트에서 DUMB로 유지되지만 검색 또는 유지 방법이 아닌 핵심 비즈니스 로직을 제공합니다.

간단히 말해서 비즈니스 오브젝트 자체 내에서 GET 및 SAVE 메소드를 통합하는 이점을 보지 못했습니다.

불평을 멈추고 준수해야합니까, 아니면 뭔가 빠졌습니까?

답변

0

DDD에 대한 이해가 없지만 1 가지 방법이 있습니다 (UPSERT를 수행합니다. 레코드가 없으면 삽입, 그렇지 않은 경우 업데이트).

클래스의 사용자는 바보처럼 행동하고 기존 레코드에 저장 및 새 레코드로 업데이트를 호출 할 수 있습니다. 하나의 행동 포인트가 훨씬 명확합니다.

편집 : INSERT 또는 UPDATE를 수행할지 여부는 저장소에 맡기는 것이 좋습니다. 사용자는 Repository.Save (....)를 호출하여 새로운 레코드 (레코드가 이미 DB에없는 경우) 또는 업데이트가 될 수 있습니다.

0

자신이 만든 방식이 마음에 들지 않으면 직접 만드십시오. 개인적으로 비즈니스 객체의 Save() 인스턴스 메소드는 나에게 정말 좋은 냄새를 풍긴다. 기억해야 할 클래스 이름이 하나 더 적습니다. 그러나 공장 저장에 문제가 없지만 둘 다 그렇게하기가 어려울 이유는 없습니다. IE

class myObject 
{ 
    public Save() 
    { 
     myObjFactory.Save(this); 
    } 
} 
... 

class myObjectFactory 
{ 
    public void Save(myObject obj) 
    { 
     // Upsert myObject 
    } 
} 
2

도메인 개체는 지속성 관련 사항에 대한 참조가 없어야합니다.

지속성 서비스를 나타내는 도메인에 저장소 인터페이스를 만들고이를 도메인 외부에 구현하십시오 (별도의 어셈블리로 구현할 수 있음).

이렇게하면 집계 루트는 리포지토리를 참조 할 필요가 없습니다 (집계 루트이므로 이미 필요한 모든 것이 있어야하므로). 종속성 또는 지속적인 관심이 없어야합니다. 따라서 테스트가 쉽고 도메인 중심입니다.

4

이것은 Active Record pattern (P of EAA p. 160 참조)로 이어집니다.

개인적으로 나는 팬이 아니다. 지속성 메커니즘을 변경하려면 비즈니스 오브젝트를 변경해야하므로 비즈니스 오브젝트와 지속성 메커니즘을 단단히 연결해야합니까? 데이터 영역을 도메인 계층과 섞어서 사용 하시겠습니까? single responsibility principle을 위반 했습니까? 내 비즈니스 개체가 Account 인 경우 Account.Save 인스턴스 메서드가 있지만 정적 메서드 Account.Find이있는 계정을 찾으려면? 불쾌한.

즉, 그것의 용도가있다. 데이터베이스 스키마에 직접적으로 따르고 단순한 도메인 로직을 가지며 테스트, 리팩토링, 의존성 삽입, 열림/닫힘, 관심사 분리 등의 문제가없는 작은 프로젝트의 경우 좋은 선택이 될 수 있습니다.

+0

바로이 부분이 액티브 레코드 대 도메인 모델입니다. 각각에는 그들의 장소, 강점 및 약점이 있습니다. –

관련 문제