DDD의 기본 원칙 중 하나는 비즈니스 규칙을 시행해야 할 장소에 가능한 한 가깝게 배치하는 것입니다. 이것은 시스템을보다 "일관성있게"만들기 때문에 매우 중요한 개념입니다. "위쪽으로"이동 규칙은 일반적으로 빈혈 모델의 표시입니다. 여기서 개체는 단지 데이터의 백이며 규칙에는 해당 데이터가 적용되어 적용됩니다.
빈혈 모델은 DDD로 시작하는 개발자에게 많은 의미가 있습니다. 이메일을 검증하는 데 필요한 정보가 주입 된 User
모델 및 모델을 작성합니다 EmailMustBeUnqiueRule
. 단순한. 우아한. 문제는 이러한 "종류의"사고는 본질적으로 기본적으로 절차 적이라는 것입니다. DDD가 아닙니다. 결국 수십 가지가 Rules
깔끔하게 포장되고 캡슐화 된 모듈이 남아 있지만 더 이상 변경이 불가능한 시점에 대한 컨텍스트가 완전히 없어서 언제 어디서 시행되는지 명확하지 않기 때문입니다. 말이 돼? 그것은 수 자명 A는 것일 EmailMustBeUnqiueRule
a의 생성에 적용됩니다 User
에 대한,하지만 UserIsInGoodStandingRule
?. 천천히 그러나 확실하게, 추출의 입자 화Rules
문맥에서 벗어나면 이해하기 어려운 시스템을 갖게되므로 변경할 수 없습니다. 실제 크 런칭 / 실행이 너무 길어서 모델이 초점을 풀기 시작할 때에 만 규칙을 캡슐화해야합니다.
이제 구체적인 질문으로 : Service
/ CommandHandler
던지기 문제 Exception
는 비즈니스 로직이 도메인에서 유출되기 시작한다는 것입니다 ( "상향"). 왜 않는 Service
/의 CommandHandler
이메일을 알 필요가 고유해야합니다? 애플리케이션 서비스 계층은 일반적으로 구현보다는 조정에 사용됩니다. ChangeEmail
시스템에 메소드 / 명령을 추가하면 간단히 그 이유를 알 수 있습니다 . 이제 두 메소드 / 명령 핸들러 모두 고유 한 검사를 포함해야합니다. 개발자가를 "추출"하려는 유혹을받는 곳 EmailMustBeUniqueRule
입니다. 위에서 설명했듯이, 우리는 그 길을 가고 싶지 않습니다.
추가적인 지식 경색은 우리에게 더 많은 DDD 답변으로 이어질 수 있습니다. 전자 메일의 고유성은 User
개체 컬렉션 전체에 적용되어야하는 고정적입니다 . 도메인에 " User
객체 컬렉션"을 나타내는 개념이 있습니까? 아마 내가 어디로 가는지 알 수있을 것 같아요.
이 특별한 경우 (그리고 여러 콜렉션에 걸쳐 불변을 적용하는 것과 관련하여)이 논리를 구현하기에 가장 좋은 장소는 귀하 Repository
입니다. 이러한 Repository
종류의 유효성 검사 (데이터 저장소)를 실행하는 데 필요한 추가 인프라를 "알기" 때문에 특히 편리합니다 . 귀하의 경우, 나는이 검사를 add
방법 에 넣을 것 입니다. 이 말이 맞습니까? 개념적으로이 방법은 User
시스템에 진정으로 a 를 추가 합니다. 데이터 저장소는 구현 세부 사항입니다.