문제

방금 읽었습니다 이 게시물 Greg Young은 Microsoft에 대해 이야기하고 있습니다. 그는 Java 공동체에서 상황이 다른 방향으로 유행하고 있음을 암시했다.

내 질문은 엔티티 객체에 얼마나 많은 논리가 있어야합니까? 내가 일하는 우리의 철학 (c# shop)은 직렬화 할 수 없다면 엔티티에 넣지 마십시오.

도움이 되었습니까?

해결책

매트,

나는 당신의 상점이 절차 코드를 작성하고 있다고 말할 것입니다. 나는 많은 대형 시스템 (내가 작업 한 많은 것을 포함하여)이 절차 코드를 사용하여 작성된 것에 아무런 문제가 없다는 것을 분명히하고 싶습니다. 그것에 대한 시간과 장소가 있습니다.

이제 절차 코드는 도메인 모델에 자리가 없습니다. 더 잘 절차 적 스타일을 사용하려면 테이블 모듈이나 활성 레코드 패턴과 같이 사용하십시오. 지침에서 그렇게 파괴적이라고 생각하는 것은 OO의 부족이 아니라 절차 논리를 가진 도메인 모델을 사용하는 것이 아닙니다.

이로 인해 도메인 계층 (일반적으로 유지 보수성)이 제공 할 수있는 이점을받지 않고 도메인 계층 (임피던스 불일치, 골재, 격리, 유비쿼터스 언어 등)을 구축하는 데 많은 양의 리소스를 소비합니다. 다시 말해서, 당신은 당신의 기능 요구 사항을 충족 할 수 있지만, 당신은 거의 수익없이 많은 예산을 소비하게됩니다.

이제 "행동"으로 돌아 오기 위해 "도메인 구동 설계"관점과는 반대로 객체 지향적 인 질문에 초점을 맞추고 싶습니다. 객체는 일반적으로 일부 상태를 캡슐화하고 일반적으로 일부 행동을 노출시킵니다.

빠른 반복 : 상태를 캡슐화하고 행동 노출

그렇다면 대상은 어떤 행동을 가져야합니까? 간단히 말해서 캡슐화하는 상태에서 작동하는 행동이어야합니다. 이상적인 행동 oo 세계에서 국가는 결코 대상 만 행동에서 노출되지 않을 것입니다. 다음과 같은 코드를보기 시작하면 전술적으로 코드에 넣습니다.

Customer c = GetCustomerFromRepository();
c.Status = CustomerStatuses.Deleted;
c.LastUpdated = DateTime.Now;
c.UpdatedBy = GetCurrentUser();
CustomerRepository.Save(c);

우리는 SRP 위반이 있습니다 ...이 코드는 고객 개체의 "책임"이기 때문에 고객 객체의 동작이어야하는 코드입니다.

고객에 대한 상태를 캡슐화하고 행동을 노출시킵니다.

따라서 우리는 고객이있는 것이 더 나을 것이라는 것을 알 수 있습니다 .Delete () 메소드. (예 이것은 내가 아는 나쁜 예입니다 ...)

이제 우리는 또한 TDD를 사용하여이를 얻을 것입니다. 모든 주가 노출되는 이음새보다 동작이 제공하는 이음새를 테스트하는 것이 훨씬 쉽습니다. 그 이유는 테스트에서 논리를 복제 할 필요가 없기 때문입니다. 클라이언트 코드는 그렇지 않습니다 케어 삭제가 작동하는 방법 ... 고객이 동작을 노출시키는 것만 관심이 있습니다. C.state == customerstates.deleted and c.updatedby == getCurrentUser () 등을 주장하는 대신 테스트에서 우리는 단순히 모의를 사용하여 삭제 방법이 고객 이음새에서 호출되었다고 주장합니다.

이제 제목으로 돌아와야합니다. 비즈니스 객체에 있어야하는 논리의 양은 상태를 캡슐화 할 책임이있는 논리의 양입니다. 때때로 이것은 많은 것입니다. 때로는 그렇지 않습니다. 서비스를 사용하고 싶은 곳이 있습니다 ... 좋은 예는 주어진 동작에 대해 많은 도메인 객체 간의 상호 작용을 조정하는 것이지만 여기서도 서비스가 전화해야합니다. 행동 도메인 객체에서.

이것이 사물을 조금 명확하게하는 데 도움이됩니까?

그렉

다른 팁

"도메인 모델 객체"라고 부르는 경우 Fowler의 도메인 모델 패턴을 언급하고 있다고 가정합니다. http://martinfowler.com/eaacatalog/domainmodel.html

그 가정을 감안할 때, 당신의 질문에 대한 답은 "모든 비즈니스 논리"입니다. 왜냐하면 그것은 본질적으로 패턴의 정의입니다.

불행히도 "도메인 모델"이라는 용어는 최근에 동작이없는 데이터의 객체 모델만을 의미하기 위해 최근에 물을 뿌린 것으로 보입니다.

당신이 아직 그렇게하지 않았다면, 나는 당신이 poeaa를 읽고 도메인 논리가 당신의 상황에 속한다고 생각하는 곳을 결정하도록 권장합니다. 도메인 모델을 결정하면 Evan의 DDD 책을 읽고 엔티티, 가치 객체 및 서비스의 차이점에 대해 배우는 것이 좋습니다.

도움이되기를 바랍니다!

최근에, 나는 구조를 가진 도메인 모델과 해당 모델에 대해 보편적 인 행동 (즉, 여러 경계 컨텍스트에서 사용할 수있는 동작) 만 제작 된 컨텍스트에 대한 행동에 대한 확장 방법을 사용한다는 아이디어를 만들어 냈습니다. . 이것은 도메인 모델을 DTO에 가깝게 유지하고 (이와 같은 사람들을 위해) 해당 도메인 모델의 사용을 제한된 컨텍스트 내에서 허용 된 동작으로만 제한합니다. 따라서 중간 도로 응답의 옵션이 될 수 있습니다. :)

요점은 논리를 정의하는 방법입니다. 몇 가지 예를 제시하려면 :

  1. 나는 개인 엔티티에서 getfullname () 함수를 분류하지 않으며, 이는 논리로 문자열을 연결합니다.
  2. 주문 항목 값을 계산하면 논리가 될 수 있습니다.
  3. 예약 거래를하는 것은 분명히 논리입니다.

지점 1과 아마도 2는 저를 엔티티로 들어갈 것입니다. 지점 3이 아닙니다. 그래서 나는 로직을 다음과 같이 정의합니다.

  • 지속성 관련 작업을 수행하는 모든 작업 (읽기/쓰기)
  • 기타 (직접 관련이 없음, 예 : 마스터-데테일)와 관련된 모든 작업

IMO, 이러한 작업 중 하나는 엔티티에 속하지 않습니다.

이제, 왜/언제, 내가 지점 1과 2 유형 작업을 엔티티에 넣지 않겠습니까? 다소 드문 상황이지만, 엔티티에 저장된 데이터를 응용 프로그램에서 사용할 수 있기 전에 어떤 방식 으로든 해석해야하자마자 (예 : 현재 사용자에 따라 필드 X의 내용 의미가 다릅니다.) 이는 엔티티의 데이터 자체가 논리를 산출 함을 의미합니다.

내가 이해하는 한, 엔티티와 관련된 모든 비즈니스 논리가 해당 엔티티로 들어가야합니다. 이것은 시스템의 비즈니스 규칙에 따라 엔티티의 행동 또는 내부 구조를 정의하는 모든 논리로 구성됩니다. 여기에는 프레젠테이션 논리 또는 지속 논리 (활성 레코드 설계 패턴과의 명백한 예외)가 포함되어서는 안되지만 데이터 검증, 엔티티 관계, 상태 기계 및 실질의 관점에서 엔티티가 어떻게 행동하는지 정의하는 기타 사항과 같은 것들이 포함되어야합니다. 세상이 모델을 만들려고합니다.

내가 그것을 보려고 노력하는 방법은 내 모델을 가능한 한 해결할 수 있도록하는 것입니다. 클라이언트 코드 (또는 엔티티를 사용하는 코드)가 다를 수있는 다른 시스템으로 포팅 될 위치가있는 경우 모델이 어떻게 사용되는지 항상 생각해보십시오. 기능이 엔티티의 일부가 아닌 경우 동일한 비즈니스 규칙에 따라 여전히 동일한 방식으로 작동합니까? 대답이 아니오라면 기능은 엔티티에 들어가야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top