나는 지금까지 약 8 년 동안 도메인 중심 디자인을 적용 해 왔으며이 모든 세월이 지난 후에도 여전히 나를 괴롭힌 한 가지가 있습니다. 그것은 도메인 객체에 대한 데이터 스토리지의 고유 레코드를 확인하는 것입니다.
2013 년 9 월 Martin Fowler는 가능한 경우 모든 도메인 객체에 적용해야하는 TellDon'tAsk 원칙을 언급했으며 ,이 메시지는 작업이 어떻게 진행되었는지 메시지를 반환해야합니다 (객체 지향 설계에서는 대부분 예외를 통해 수행됩니다 작업이 실패했습니다).
내 프로젝트는 일반적으로 여러 부분으로 나뉘며, 그 중 두 개는 도메인 (비즈니스 규칙을 포함하고 그 밖의 다른 것, 도메인은 완전히 영속 무지 함)과 서비스입니다. 데이터를 CRUD하는 데 사용되는 저장소 계층에 대해 알고있는 서비스
오브젝트에 속하는 속성의 고유성은 도메인 / 비즈니스 규칙이므로 도메인 모듈까지 길어야하므로 규칙이 정확히 있어야합니다.
레코드의 고유성을 확인하려면 현재 데이터 세트 (일반적으로 데이터베이스)를 쿼리하여 다른 레코드가 Name
이미 존재 하는지 확인해야 합니다.
도메인 계층이 지속성을 모르고 데이터를 검색하는 방법을 모르지만 작업을 수행하는 방법 만 알면 실제로 저장소 자체를 건드릴 수 없습니다.
내가 적응 한 디자인은 다음과 같습니다.
class ProductRepository
{
// throws Repository.RecordNotFoundException
public Product GetBySKU(string sku);
}
class ProductCrudService
{
private ProductRepository pr;
public ProductCrudService(ProductRepository repository)
{
pr = repository;
}
public void SaveProduct(Domain.Product product)
{
try {
pr.GetBySKU(product.SKU);
throw Service.ProductWithSKUAlreadyExistsException("msg");
} catch (Repository.RecordNotFoundException e) {
// suppress/log exception
}
pr.MarkFresh(product);
pr.ProcessChanges();
}
}
이로 인해 도메인 계층 자체가 아닌 도메인 규칙을 정의하는 서비스가 제공되고 코드의 여러 섹션에 규칙이 분산됩니다.
TellDon'tAsk 원칙을 언급했습니다. 분명히 알 수 있듯이 서비스는 작업을 제공 Product
하지만 (예외를 저장 하거나 예외를 발생) 메소드 내부에서는 절차 적 접근 방식을 통해 객체에 대해 작업합니다.
확실한 해결책은을 던지는 메소드 로 Domain.ProductCollection
클래스 를 작성하는 것이지만 제품에 이미 동일한 SKU가 있는지 여부를 코드에서 찾으려면 데이터 스토리지에서 모든 제품을 가져와야하므로 성능이 많이 부족합니다. 추가하려는 제품으로Add(Domain.Product)
ProductWithSKUAlreadyExistsException
이 특정 문제를 어떻게 해결합니까? 이것은 실제로 그 자체로 문제가되지는 않습니다. 서비스 계층에서 수년간 특정 도메인 규칙을 대표했습니다. 서비스 계층은 일반적으로 더 복잡한 도메인 작업을 제공합니다. 커리어 중에 더 중앙 집중화 된 솔루션을 발견했는지 궁금합니다.