DDD-많은 수의 자식이있는 집계 루트


10

나는 DDD에 비교적 익숙하지 않다고 말함으로써이 질문의 머리말을 쓸 것이다.

나는 회계 및 거래 개념 (재무 적 의미)을 포함하는 프로젝트를 진행하고 있습니다. 계정에는 많은 거래가 입력 될 수 있습니다.

계정과 거래는 모두 엔터티이며 거래는 계정없이 존재할 수 없으므로 계정은 거래를 포함하는 집계 루트 인 것 같습니다.

그러나 이것을 코드에 적용하려고하면 즉시 문제가 발생했습니다. 많은 상황에서 계정의 모든 거래 목록을 항상 가지고있는 것이 특히 유용하지는 않습니다. 계정 잔액 계산 및 신용 한도 등의 불변량 시행과 같은 일에 관심이 있지만 거래 하위 집합 (예 : 날짜 범위에 해당하는 항목 표시)으로 쉽게 작업 할 수 있기를 원합니다.

후자의 경우, 내가 사용하는 TransactionRepository경우 전체 (잠재적으로 매우 큰) 목록을로드하지 않고도 필요한 객체에 효율적으로 액세스 할 수 있습니다. 그러나 이것은 계정 이외의 것들이 거래와 함께 작동하도록 허용합니다. 즉, 계정 개념을 총체 루트로 깨뜨 렸습니다.

사람들은 이런 상황을 어떻게 처리합니까? 집계 루트에 잠재적으로 많은 수의 자식을로드 할 때 메모리와 성능에 미치는 영향을 받아들입니까?

답변:


9

"없이는 존재할 수 없습니다" 규칙 에주의하는 것이 좋습니다 . 이것은 UML / OO 디자인의 구성 개념에 대해 말하고 원래 DDD 청서 (그 확실하지 않음)에서 집계를 디자인하는 데 지정된 방법 중 하나 였지만 그 이후로 크게 수정되었습니다. 트랜잭션 일관성 경계 관점 에서 집계를 보는 것이 좋습니다 .

어떤 불변이 불가피하게 여러 집계에 걸쳐서 집계 잠금 및 동시성 문제를 유발하기 때문에, 집계가 너무 커지거나 지적한 것과 같은 성능 문제가 발생하거나 너무 작아지는 것은 아닙니다.

올바른 집계 크기는 주어진 비즈니스 트랜잭션에서 수정 한 형상과 이상적으로 이상적으로 일치합니다. 예를 들어, 여러 금융 거래에 걸쳐 도메인 불변이 많지 않은 경우 Transaction집계 루트를 자체적으로 만드는 것이 가장 좋은 솔루션 일 수 있습니다.


감사합니다. 일관성 경계에 대해 읽어 보겠습니다. Transaction을 자체 집계 루트로 만들 겠다는 귀하의 제안이 좋을 것 같습니다. 당신이 말했듯이 여러 거래에 걸쳐 많은 불변이 없습니다.
krixon

7

tl; dr-필요한 경우 규칙을 어기십시오. DDD는 모든 문제를 해결할 수는 없습니다. 실제로 그것이 제공하는 객체 아이디어는 좋은 조언과 좋은 출발이지만, 일부 비즈니스 문제에 대한 선택은 좋지 않습니다. 일을하는 방법에 대한 힌트를 고려하십시오.


부모 (계정)로 모든 어린이 (트랜잭션)를로드하는 문제-많은 ORM이 해결 한 n + 1 문제 (Google에 문제가 있음)가 발생한 것처럼 보입니다.

필요할 때만 자식을 게으르게로드 (트랜잭션)하여 해결할 수 있습니다.

그러나 TransactionRepository를 사용하여 문제를 해결할 수 있다고 언급함으로써 이미 알고있는 것처럼 들립니다.

계정 만 데이터를 사용할 수 있도록 해당 데이터를 '숨기려면'공개 관계형 테이블과 같이 다른 사람이 데이터를 역 직렬화하는 방법이없는 곳에 데이터를 저장하지 않아도됩니다. 계정의 '문서'와 함께 문서 DB에 저장할 수 있습니다. 어느 쪽이든 누군가가 열심히 노력하면 여전히 데이터를 볼 수 있습니다. 그리고 '작업'. 그리고 당신이 보이지 않을 때, 그들은 할 것입니다!

따라서 권한을 설정할 수 있지만 별도의 프로세스로 '계정'을 실행해야합니다.

여기서 실제로 깨닫는 것은 DDD와 객체 모델의 순수한 사용이 때때로 당신을 코너로 되돌려 놓을 것이라는 것입니다. 물론 DDD의 디자인 원칙을 활용하기 위해 '구성'/ 집계 루트를 사용할 필요는 없습니다. 제약 조건에 맞는 상황이있을 때 사용할 수있는 것은 단 하나입니다.

누군가는 '조기 최적화하지 마십시오'라고 말할 수 있습니다. 그러나이 경우 대답을 알 수 있습니다-계정과 함께 모든 것을 영원히 유지할 수있는 방법을 정리하기에 충분한 트랜잭션이 있습니다.

진정한 대답은 SOA를 시작하는 것입니다. 직장에서 우리는 Udi Dahan '분산 컴퓨팅'비디오를보고 nServiceBus (우리의 선택)를 구입했습니다. 자체 프로세스, 메시지 큐, 볼 수있는 관계 데이터베이스에 대한 액세스만으로 계정에 대한 서비스를 작성하십시오. ... ... 비올라를 사용하면 프로그램에서 SQL 문을 하드 코딩하고 몇 가지 Cobol 트랜잭션 스크립트 (트레이닝)를 수행 할 수도 있습니다. 물론) 가장 똑똑한 OO / Java snob이 꿈꿔 왔던 것보다 더 많은 관심사 분리가 있습니다.

어쨌든 잘 모델링하는 것이 좋습니다. 서비스를 미니 바운드 카운트로 취급하면 문제없이 집계 루트의 이점을 얻을 수 있습니다.

물론 단점이 있습니다. 서비스 안팎에서 RPC (웹 서비스, SOAP 또는 REST)를 할 수 없으며 서비스 간 또는 시간 결합으로 인해 '매듭'이라는 SOA 반 패턴을 얻을 수 없습니다. 이벤트 처리기 및 이벤트 발생기와 마찬가지로 통신 패턴의 역전, 즉 'Pub-Sub'를 사용해야합니다.

실제 문제는 다른 서비스에서 데이터를 '차단'하거나 기다리는 데 필요한 서비스를 원하지 않는다는 것입니다. 메시지를 발생시키고 잊어 버리고 프로그램의 다른 곳에서 처리기가 처리를 완료하도록해야합니다. 이것은 논리를 다르게해야한다는 것을 의미합니다. nServicebus는이 중 일부를 돕기 위해 '사가'패턴을 자동화하지만 결국 다른 코딩 스타일을 개발해야합니다. 당신은 여전히 ​​모든 일을 할 수 있습니다. 다른 방식으로해야합니다!

Arnon Rotem-Gal-Oz의 "SOA Patterns"책은 이것에 대한 많은 질문에 답합니다. '액티브 서비스 패턴'사용을 포함하여 필요할 때 외부 서비스에서 사용자 자신의 데이터를 주기적으로 복제합니다 (많은 RPC가 필요했거나 링크가 신뢰할 수 없거나 발행 / 구독 에코 시스템에없는 경우).

미리보기 만하면 UI 서비스에 RPC를 제공해야합니다. 서비스 데이터베이스가 제공하는보고 데이터베이스에서 보고서가 생성됩니다. 어떤 사람들은 보고서가 필요하지 않으며 문제를 다른 방법으로 해결해야한다고 말합니다. 그 이야기에 회의적하십시오.

결국 모든 것을 단일 서비스로 올바르게 분류 할 수있는 것은 아닙니다. 세계는 라비올리 코드에서 실행되지 않습니다! 따라서 규칙을 어겨 야합니다. 전혀 필요하지 않더라도 프로젝트의 새로운 개발자는 프로젝트를 떠날 때 수행합니다. 그러나, 당신이 할 수있는 일을한다면, 규칙을 따르는 85 %가 훨씬 더 유지 보수가 쉬운 프로그램을 만들 것입니다.

와우, 그것은 길었다.


자세한 답변을 보내 주셔서 감사합니다. SOA에 대해 자세히 읽어 보겠습니다.
krixon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.