2009-09-14 4 views
1

나는 집계의 일부인 엔티티의 변경 사항을 감지하기 위해 사람들이 취했을 수있는 접근 방법을보고자합니다. 나는 효과가있는 것을 가지고 있지만, 그것에 대해 미치지 않습니다. 기본적으로 저장소는 집계 루트의 상태가 변경되었는지 여부를 결정합니다. 집계 루트가 Book이고 집계 내에 Page이라는 엔티티가 있다고 가정 해 보겠습니다. BookPages 컬렉션에 저장된 하나 이상의 Page 엔티티를 포함합니다.집계 루트에서 엔티티의 변경 감지

기본적으로 삽입 및 업데이트 시나리오는 집계 루트와 그 엔티티를 검사하여 키의 존재를 판별함으로써 수행됩니다. 키가있는 경우 개체가 한 번에 원본 데이터 원본에 저장되었다고 가정합니다. 이로 인해 업데이트 후보가됩니다. 엔티티만으로는 그 사실에 근거하여 결정적인 것은 아닙니다. 집계 루트를 사용하면 대답이 분명합니다. 단 하나만 존재하고 그것이 유일한 입력 지점이기 때문에 키 존재가 작업을 지시한다고 가정 할 수 있습니다. 내 경우에는 집계 루트를 다시 저장하여 수정 날짜를 캡처 할 수 있습니다.

엔터티 자체에 대한이 동작을 용이하게하기 위해 IsUpdated(), IsDeleted()의 두 가지 간단한 속성이 내 EntityBase 클래스에 포함되어 있습니다. 이 두 가지 모두 기본값은 false입니다. 이전에 언급 한 것처럼 키의 존재 여부에 따라 결정을 내릴 수 있기 때문에 새로운 것인지 아닌지 알 필요가 없습니다. 구현의 메소드 (이 경우에는 Page)에는 보조 데이터 세트 IsUpdated()을 true로 변경하는 각 메소드가 있습니다.

예를 들어, Page는 속성의 백킹 값을 읽기 전용으로 변경하는 UpdateSectionName()이라는 메서드가 있습니다. 이 접근법은 데이터 설정을 수행하는 (엔터티가 잘못된 상태로 들어가는 것을 방지하는) 메서드에서 유효성 검사기의 논리적 인 접속 지점을 허용하므로 일관되게 사용됩니다. 최종 결과는 메소드 끝에 this.IsUpdated() = true;을 넣어야한다는 것입니다.

집계 루트는 Save() (AN Insert() 또는 Update() 작업 중 하나에 논리 스위치), 그 다음 1 ~ 3을의 가지고있는 페이지를 찾고 BookPages 컬렉션을 반복 할 수의 저장소로 전송 될 때 시나리오 :

  1. 키가 없습니다. 키가없는 Page이 삽입됩니다.
  2. IsDeleted = true; 삭제는 업데이트보다 우선하며, 삭제는 커밋됩니다. Page에 대한 업데이트는 무시하십시오.
  3. IsUpdated = true; 페이지에 대한 업데이트가 커밋됩니다.

이렇게하면 페이지 컬렉션에있는 모든 것을 맹목적으로 업데이트하는 것을 방지 할 수 있습니다. 예를 들어 책에 수백 개의 페이지 엔터티가있는 경우 문제가 될 수 있습니다. 나는 책의 사본을 가져 오는 것을 고려하고 있었고 비교를하고 변화를 감지하고 (존재감 및/또는 비교에 기초한 삽입, 업데이트 및 삭제) 변경 사항을 확인했지만 그 일에 대해서는 상당히 혼란 스러웠다. .

주요 단점은 개발자가 엔티티의 각 메소드에서 IsUpdated를 설정해야한다는 점입니다. 하나를 잊어 버리면 해당 값의 변경 사항을 감지 할 수 없습니다. 변경 사항을 투명하게 타임 스탬프 할 수있는 일종의 사용자 지정 백업 저장소에 대한 아이디어를 가지고 놀랐습니다. 그러면 IsUpdated은 리포지토리가 업데이트를 집계하는 데 사용할 수있는 읽기 전용 속성이 될 수 있습니다.

리포지토리는 집계 루트가 추가되었을 때 생성 된 타임 스탬프에서 작업을 기반으로하는 작업 단위 패턴 구현을 사용하고 있습니다. 연산을 위해 대기중인 여러 엔티티가있을 수 있으므로 엔티티 연산은 겹쳐서 실행되고 집계 루트 연산이 실행되면 엔티티가 속합니다. 나는 한 걸음 더 나아가 엔티티 작업을 처리하고 엔티티에서 사용되는 일종의 이벤트 추적을 기반으로하는 다른 작업 단위를 생성하는 것을 볼 수있었습니다 (이는 내가 시장에서 ORM 제품 중 일부가 수행한다고 가정하는 방법입니다). 비슷한 수준의 기능성).

나는 계속이 방향으로 움직이기 전에, 나는 이것에 관한 아이디어/추천/경험을 듣고 싶다.

편집 : 도움이 될 수있는 정보의 몇 가지 추가 조각 알아야 할 사항

  1. 내가 함께 일하고 현재 언어는 C#을, 내가 많은 언어 별 정보를 유지하기 위해 노력하지만, 이것은 이론적 인 논의가 더 많기 때문에 가능하면.
  2. 리포지토리/서비스/엔티티/코드의 코드입니다. Tim McCarthy의 저서 ".NET Domain-Driven Design with C#"과 지원 코드 CodePlex을 기반으로합니다. 취해진 접근법의 유형에 대한 실행 가능한 이해를 제공합니다. 비록 제가 작업하고있는 것이 크게 근본적으로 다시 작성되었지만 말입니다.

답변

1

간단히 말해서, 제 대답은 내가 제안한 것과 함께 갔다는 것입니다. 그것은 개선의 여지가 있다고 확신하지만 작동하고 있습니다. 변경 작업은 실제로 거의 시간이 걸리지 않았으므로이 경우 KISS 또는 YAGNI 교장에서 너무 멀리 탐색하지 않은 것으로 느낍니다. :-)

운영에 타이밍 관련 문제가 발생할 여지는 여전히 있지만, 저장소 구현에서 문제를 해결할 수 있어야합니다. 이상적인 해결책은 아니지만 문제를 해결하기 위해 바퀴를 다시 발명 할 가치가 있는지 확신 할 수 없습니다. 문제를 해결하는 데 걸리는 시간보다 짧은 시간에 피할 수 있습니다.