2009-09-25 4 views
6

메모리 변경시 CQS를 구현하는 방법은 무엇입니까?

http://www.infoq.com/interviews/greg-young-ddd

DDD

에 그렉 Yound하여이 비디오를 시청 데 난 당신이 메모리 변경에있을 때 DDD와 명령 쿼리 분리 (CQS)를 구현할 수 궁금 해서요?

CQS에는 명령과 쿼리를위한 두 개의 리포지토리가 있습니다. 두 개의 개체 그룹, 명령 개체 및 쿼리 개체. 명령 개체에는 메서드 만 있고 개체의 모양을 노출시킬 수있는 속성이 없으며 화면에 데이터를 표시하는 데 사용되지 않습니다. 반면에 쿼리 개체는 화면에 데이터를 표시하는 데 사용됩니다.

비디오에서 명령은 항상 데이터베이스로 이동하므로 쿼리 리포지토리를 사용하여 업데이트 된 데이터를 가져 와서 화면에 다시 표시 할 수 있습니다.

CQS를 ASP.NET의 화면 편집과 같이 사용할 수 있습니까? 변경 사항이 메모리에 변경되고 화면이 변경 사항을 여러 번 업데이트해야 변경 사항이 데이터베이스에 유지됩니다. 예를 들어

  1. 나는
  2. 내가 쿼리 객체 저장소에서 질의 객체를 다시 반입과에 표시 편집
  3. 을 클릭 쿼리 저장소에서 질의 객체를 가져 와서 화면에 표시 양식 편집 모드
  4. 양식의 값을 변경하여 자동 포스트 백하고 명령 개체를 반입하고 관련 명령을 실행합니다.
  5. 수행 할 작업 : 이제는 upda를 표시해야합니다. ted 오브젝트가 명령 필드로 변경되면서 계산 된 필드가 변경됩니다. 명령 개체가 데이터베이스에 저장되지 않았으므로 쿼리 리포지토리를 사용할 수 없습니다. 그리고 CQS를 사용하면 화면에 표시 할 명령 개체의 모양이 노출되지 않습니다. 업데이트 된 변경 내용을 화면에 표시하기 위해 쿼리 개체를 다시 얻는 방법은 무엇입니까?

내가 생각할 수있는 몇 가지 해결책은 세션 저장소 또는 명령 개체에서 쿼리 개체를 가져 오는 방법입니다. CQS가 이러한 유형의 시나리오에 적용되지 않습니까?

비디오 변경 사항이 데이터베이스에 즉시 반영되고 CQS와 함께 DDD의 예가 도메인 개체의 변경 사항을 일괄 적으로 처리하고 마지막으로 도메인 객체를 저장하라는 명령을 내리기 전에 수정 된 도메인 객체.

답변

1

정말로 CQS를 사용하려는 경우 Query repo와 Write repo 모두에 동일한 백업 저장소에 대한 참조가 있습니다.일반적으로이 참조는 외부 데이터베이스를 통해 이루어 지지만, 귀하의 경우에는 목록 <T> 또는 그와 비슷한 것일 수 있습니다.

+1

답장을 보내 주셔서 감사합니다. 데이터베이스에 직접 반영되지 않고 변경 사항이 메모리에있을 때 CQS를 사용하는 것이 얼마나 일반적인지/좋은 디자인인지 궁금합니다. 이것은 기본적으로 세션 저장소를 사용하여 쿼리 리포지토리가 세션 변수를 통해 명령 데이터에 액세스 할 수있게하는 것입니다. 나중에 HttpContext 리포지토리가 필요할 수 있습니다. 이전에 본 사람이 있습니까? 생각은 감사했다. – Ian

+0

제 생각에는 데이터 원본을 조작하는 데 사용하는 메서드가 데이터 원본의 종류에 의존하지 않아야합니다. 리포지토리 패턴을 사용하면 이러한 차이점을 추상화하여 쿼리 할 수있는 개체 컬렉션 인 것처럼 모든 데이터 원본을 처리 할 수 ​​있습니다.이론적으로는 'InMemoryRepository'와 'DatabaseRepository'를 갖게 될 것입니다 - 또는 무엇을 가지고있을 것인가는 대상 데이터 소스를 결정하는 것은 개별 저장소 구현에 달려 있습니다. –

+0

네, 데이터베이스 저장소를 위해 InMemory 저장소를 바꿀 수 있다는 것을 알고 있습니다. CQS의 가치 중 일부는 데이터베이스에 명령을 실행하고 업데이트 된 데이터를 쿼리 리포지토리와 별도로 되돌려 놓는 것입니다. 메모리에서 명령 개체는 세션에 있으므로 쿼리 리포지토리는 명령 개체의 데이터 만 되돌릴 수 있습니다. 데이터베이스 버전을 사용하면 쿼리 개체가 명령 개체와 완전히 다를 수 있으며 메모리 CQS와의 관계가 훨씬 비슷해 보입니다. 이것이 CQS가 성취하려고 시도한 것과 어울리는지 궁금합니다 – Ian

0

메모리에 일반적으로 Observer design pattern을 사용합니다.

실제로이 패턴을 사용하고 싶지만 대부분의 데이터베이스는 DB의 내용이 변경 될 때 앱의 메소드를 호출하는 효율적인 방법을 제공하지 않습니다.

+0

확실하지를 제공합니다. CQS를 사용하면 읽기와 쓰기를 분리 할 수 ​​있습니다. Query 저장소가 Write 저장소와 분리 된 곳. 도메인 엔터티를 리포지토리에 저장하지 않으면 쿼리 리포지토리가 데이터를 가져올 수있는 방법은 무엇입니까? 업데이트 된 상태로 도메인 개체에서 쿼리 개체를 가져 오는 방법이 필요합니까, 아니면 쿼리 개체가 도메인 개체를 관찰하고 자체를 업데이트한다고 말하고 있습니까? 또는 세션 저장소를 도입 할 수 있습니까? – Ian

0

에서 디자인 패턴은 Patterns of Enterprise Application Architecture입니다. CQS와 잘 일치합니다. 기본적으로 데이터베이스에 항목을 저장하는 큰 명령입니다.

+0

링크 주셔서 감사하지만 여전히 내 질문에 대답하지 않습니다. 기본적으로 CQS에는 메서드 (명령) 만있는 개체와 개체 모양이 포함 된 개체가 있습니다. 두 개의 리포지토리가 있습니다. 하나는 명령 개체 용이고 다른 하나는 쿼리 개체 용입니다. 명령 개체를 사용하여 화면을 다시 채우지 않고 대신 쿼리 개체를 사용합니다. 명령 개체의 변경 내용을 데이터베이스에 저장하지 않고 명령을 호출하여 변경 한 내용을 다시 표시하려면 어떻게해야합니까? 변경 사항이 데이터베이스에 없으므로 쿼리 리포지토리를 사용할 수 없습니다. – Ian

3

그래서 여기에서 원하는 것은 좀 더 세부적인 명령입니다.

EG : 사용자가 웹 페이지와 상호 작용합니다 (장바구니로 결제하는 경우).

정보를 얻는 여러 페이지가 명령을 작성하고 있습니다. 이 명령은 사용자 이 실제로까지 모든 정보가 도메인에 단일 명령으로 전송 된 곳을 체크 아웃 할 때까지 전송되지 않습니다.이 명령을 "CheckOut"명령이라고합니다.

프리젠 테이션 모델은 이러한 유형의 상호 작용을 추상화하는 데 매우 유용합니다.

희망이 도움이됩니다. 우려의 나머지 부분에 대한 또 그렉

+0

안녕 Greg, 예를 들어 보셨습니까? 현재 쿼리 개체를 가져 오는 경로가 중단되어 포스트 백 간의 변경을 허용하도록 쿼리 개체를 serialize하는 "장바구니"개체에 넣습니다 (세션도 사용할 수 있음). 개체가 업데이트되면 명령 개체로 전달됩니다. 시간이 더 많은 경우 쿼리 개체와 다른 개체를 사용하여 프레젠테이션 모델과 같은 편집 변경 내용을 저장할 수 있습니다. 동일한 개체를 사용하여 표시하고 수정하는 경우 제안 된 프레젠테이션 모델과 동일합니까? 감사합니다. – Ian

1

...

은 두 개 때문에 최종 일관성에 문제가 CQRS에 반대한다. 결과적으로 CQRS와의 일관성을 유지할 필요가 없기 때문에 명령의 처리를보고 저장소에 쓰거나 일관된 방식으로 둘 다에 대해 동일한 실제 저장소를 사용할 수 있습니다. 실제로 사람들은 기본 아키텍처로 이것을 수행하고 나중에 필요할 때 어디서나 일관성을 유지할 것을 권장합니다. 당신이 내 질문을받을 경우

+0

내 상황에 적용되는지 아직 확실하지 않지만 지금까지는 하나의 데이터베이스 만 있으므로보고 저장소를 업데이트하는 것에 대해 걱정할 필요가 없으며 명령 개체가 NHibernate를 사용하여 변경 사항이 데이터베이스에 다시 유지됩니다. 또는 내 상황에도 적용됩니까? 어떤 부분에 대해 당신이 우려하고 있는지 확실하지 않습니다. – Ian

-2

JdonFramework이 CQRS DDD 자바 프레임 워크, 그것은 도메인 이벤트 + 비동기 패턴, 자세한 내용은 https://jdon.dev.java.net/