-
AGGREGATE와 REPOSITORY 5부JAVA/DDD 2021. 1. 8. 19:48
ENTRY POINT와 REPOSITORY
- 주문은 주문 AGGREGATE의 ENTRY POINT이다.
- 따라서 주문이 필요한 경우 OrderRepository를 통해 해당 주문 객체를 얻을 수 있다.
- 그럼 특정한 고객에 대한 주문 목록을 얻어야 한다면 어떻게 해야 할까?
- 쉽게 생각해 볼 수 있는 방법은 CustomerRepository로부터 고객 객체를 얻은 후 연관을 통해 해당하는 Order 객체들에게 접근하는 것이다.
- 그러나 이 방법은 Order와 Customer 클래스 간에 양방향 연관 관계를 추가한다.
- 특정 객체에 속하는 다른 객체들을 조회하는 요구사항마다 양방향 연관 관계를 설정한다면 감당하기 어려울 정도로 모델이 복잡해질 것이다.
- 고객에 해당하는 주문 목록을 조회하는 적절한 방법은 OrderRepository에 고객 별 주문 목록을 조회하는 메서드를 추가하는 것이다.
- OrderRepository는 Order의 컬렉션을 관리하기 위해 추가된 PURE FABRICATION이다.
- 따라서 주문 객체를 얻기 위해 OrderRepository를 사용하는 것은 논리적으로 타당할 뿐만 아니라 주문 객체에 접근하기 위한 일관성 있는 방법을 제공한다.
- 또한 OrderRepository를 통해 Order와 Customer 간의 양방향 연관 관계를 방지할 수 있다.
- OrderRepository에 기능을 추가하기 전에 실패하는 테스트부터 작성하자.
- 테스트가 OrderRepository에OrderRepositoryTest 클래스를 추가한 후 테스트 메서드를 작성하자.
1234567891011121314151617181920212223242526public class OrderRepositoryTest extends TestCase {private Customer customer;private OrderRepository orderRepository;private ProductRepository productRepository;public void setUp() throws Exception {Registrar.init();orderRepository = new OrderRepository();productRepository = new ProductRepository();productRepository.save(new Product("상품1", 1000));productRepository.save(new Product("상품2", 5000));customer = new Customer("CUST-01", "홍길동", "경기도 안양시", 200000);}public void testOrdreCount() throws Exception {orderRepository.save(customer.newOrder("CUST-01-ORDER-01").with("상품1", 5).with("상품2", 20).with("상품1", 5));orderRepository.save(customer.newOrder("CUST-01-ORDER-02").with("상품1", 20).with("상품2", 5));assertEquals(2, orderRepository.findByCustomer(customer).size());}}cs - 두 번의 주문을 수행하여 생성된 Order 객체를 OrderRepository에 추가한다.
- 단언 문을 사용하여 고객에게 속한 주문이 두 건인지를 검증한다. 이제 OrderRepository에 findByCustomer() 메소드를 추가하자.
1234567891011121314151617OrderRepository.javapublic Set<Order> findByCustomer(Customer customer) {Set<Order> results = new HashSet<Order>();for(Order order : findAll()) {if (order.isOrderedBy(customer)) {results.add(order);}}return results;}@SuppressWarnings("unchecked")public Set<Order> findAll() {return new HashSet<Order>((Collection<Order>)Registrar.getAll(Order.class));}}cs - findByCustomer() 메소드는 전체 주문 중에서 특정 고객에 속한 주문의 컬렉션을 반환한다.
- Order가 Customer 정보를 알고 있으므로 INFORMATION EXPERT 패턴에 따라 고객에 포함되어 있는지 여부를 판단할 수 있는 isOrderedBy() 메소드를 Order에 추가한다.
12345Order.javapublic boolean isOrderedBy(Customer customer) {return this.customer == customer;}cs - Customer 클래스가 REFERENCE OBJECT이고 CustomerRepository에 의해 유일성과 추적성이 보장되므로 동등성 비교를 위해 ”==” 연산자를 사용했다.
- 테스트는 이제 성공한다.
- 주문도 정상적으로 처리되고 불변식도 위반하지 않고 중복되는 주문 항목도 없고 고객의 주문 목록도 조회할 수 있게 되었다.
참조
'JAVA > DDD' 카테고리의 다른 글
DDD - Dependency Injection과 AOP 2부 (0) 2021.01.22 DDD - Dependency Injection과 AOP 1부 (0) 2021.01.11 AGGREGATE와 REPOSITORY 4부 (0) 2021.01.05 Aggregate와 Repository 3부 (0) 2020.12.30 AGGREGATE와 REPOSITORY 2부 (0) 2020.12.29