도메인주도개발

애그리거트를 팩토리를 사용하기

OverTheHorizon3410 2024. 1. 2. 22:16

상황

고객이 특정 상점을 여러 차례 신고하여 차단된 상태에서

상점이 물건을 등록하지 못하도록 하는 상황을 가정

상품 등록 기능을 구현한 응용 서비스는 상점 계정이 차단 상태가 아닐 때만 상품을 생성할 수 있다.

기존 응용 서비스 코드 예시

public class RegisterProductService {
    public ProductId registerNewProduct(NewProductRequest req) {
        Store store = storeRepository.findById(req.getStoreId());
        checkNull(store);
        
        if (store.isBlocked()) {
            throw new StoreBlockedException();
        }
        
        ProductId id = productRepository.nextId();
        Product product = new Product(id, store.getId(), ...);
        productRepository.save(product);
        
        return id;
    }
}
  • 서비스 레이어에 상품을 생성하는 로직이 응용 서비스에 노출되어 있음.
  • Store 가 Product 를 생성할 수 있는지 판단하고 생성하는 것이 도메인의 기능임에도..
    • 응용 서비스 단에서 구현되고 있다.

개선된 도메인 서비스 코드 예시

public class Store {
    public Product createProduct(ProductId newProductId, ...) {
        if (isBlocked()) {
            throw new StoreBlockedException();
        }
        return new Product(newProductId, getId(), ...);
    }
}
  • Store 애그리거트에서 createProduct 메서드는 Product 애그리거트를 생성하는 팩토리 메서드의 역할을 한다.

개선된 서비스 레이어 코드 예시

public class RegisterProductService {
    public ProductId registerNewProduct(NewProductRequest req) {
        Store store = storeRepository.findById(req.getStoreId());
        checkNull(store);
        
        ProductId id = productRepository.nextId();
        Product product = store.createProduct(id, ...);
        productRepository.save(product);
        
        return id;
    }
}
  • Store 의 상태를 직접 확인 X
  • Store 도메인 로직 안에서 Product 생성 가능 여부를 판단한다.
    • 도메인 로직 변경시 Store 만 수정하면 되고, 응용 서비스는 영향을 받지 않는다.
    • 도메인의 응집도가 높아짐.

위임을 통한 팩토리의 구현

public class Store {
    public Product createProduct(ProductId newProductId, ProductInfo pi) {
        if (isBlocked()) {
            throw new StoreBlockedException();
        }
        return ProductFactory.create(newProductId, getId(), pi);
    }
}
  • Store 애그리거트가 Product 애그리거트를 생성시, 필요한 정보가 많다면,
    • 다른 팩토리에 생성을 위임도 가능합니다.


Uploaded by N2T