JAVA/DDD
-
DDD - Dependency Injection과 AOP 6부 7부JAVA/DDD 2021. 1. 23. 12:40
관점을 바꾸자 ProductRepository의 경우와 마찬가지로 CustomerRepository와 OrderRepository에 EXTRACT INTERFACE리팩토링을 수행하자. 즉 CustomerRepository, OrderRepository 인터페이스와 CollectionCustomerRepository, CollectionOrderRepository 클래스로 분리하자. Registrar에 대한 setter 메소드를 추가한 후 이들을 Spring 빈 컨텍스트에 정의한다. 기존의 테스트 케이스들이 Spring 경량 컨테이너의 지원을 받을 수 있도록 테스트 케이스를 수정하자. 우선 OrderTest 클래스를 ProductRepositoryTest와 동일한 방식으로 getConfigLocations..
-
DDD - Dependency Injection과 AOP 4부 5부JAVA/DDD 2021. 1. 22. 22:17
우선 ProductRepository를 리팩토링하자. 구체적인 클래스에서 인터페이스를 추출하는 EXTRACT INTERFACE를 적용하자. 인터페이스 명은 ProductRepository로 하고 구현 클래스 명은 CollectionProductRepository로 하자. 1 2 3 4 5 6 7 8 9 10 ProductRepository.java public interface ProductRepository { public void save(Product product); public Product find(String productName); } Colored by Color Scripter cs 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CollectionProduc..
-
DDD - Dependency Injection과 AOP 3부JAVA/DDD 2021. 1. 22. 22:03
영속성(Persistence)과 REPOSITORY REPOSITORY는 도메인 객체 생성 이후의 생명주기를 책임진다. 도메인 객체가 생성되고 상태가 초기화된 후에는 REPOSITORY에게 넘겨진다. REPOSITORY는 객체를 넘겨받아 내부 저장소에 보관하고 요청이 있을 경우 객체를 조회하여 반환하거나 삭제한다. 클라이언트 입장에서 REPOSITORY는 커다란 메모리에 도메인 객체들을 담고 있는 객체 풀(object pool)과 같다. 클라이언트는 생성된 객체를 REPOSITORY에게 전달하고 객체가 필요한 경우 REPOSITORY에게 객체 풀 안의 어딘가에 잠자고 있는 도메인 객체를 찾아 달라고 요청한다. REPOSITORY의 기능을 메모리 컬렉션에 대한 오퍼레이션으로 바라보는 것은 도메인 모델을 단..
-
DDD - Dependency Injection과 AOP 2부JAVA/DDD 2021. 1. 22. 21:41
객체 그리고 영속성(Persistence) 모든 객체는 생성자가 호출되는 시점에 생성된다. VALUE OBJECT의 수명은 짧다. 생성된 후 잠시 다른 REFERENCE OBJECT 또는 VALUE OBJECT에 의해 사용되다가 다른 VALUE OBJECT로 대체된다. 갈 길을 잃은 VALUE OBJECT는 가비지 컬렉터에게 넘겨진 후 조용히 생을 마감한다. VALUE OBJECT에 비해 REFERENCE OBJECT의 수명은 상대적으로 길다. REFERENCE OBJECT는 다양한 이벤트에 반응함에 따라 상태가 변한다. 일단 고객 객체가 생성되면 시스템은 고객이 탈퇴할 때까지 고객 객체를 참조하고 추적할 수 있어야 한다. 이를 위해 도메인 모델에 추가되는 PURE FABRICATION이 REPOSITO..
-
DDD - Dependency Injection과 AOP 1부JAVA/DDD 2021. 1. 11. 19:29
애플리케이션의 모든 기억들은 종료되는 순간 깨끗하게 증발돼 버리고 만다. 애플리케이션은 상태를 끊임없이 기록하고, 기억을 재생하고, 현실을 재구성해야 한다. 유효 시간이 지나고 단기 기억 상실증으로 인해 모든 기억이 소멸되더라도 기록을 통해 어플리케이션의 기억을 되돌릴 수 있어야 한다. 애플리케이션이 기억을 재생할 수 있다고 해서 모든 기억을 동시에 복구하는 것은 소모적인 일이다. 살아오면서겪은 모든 일들을 일일이 다 기억하고 있을 수는 없다. 애플리케이션 역시 마찬가지다. 지금 처리하기 위해 필요한 최소한의 정보만 기억하고 있으면 된다. 시스템의 메모리는 한정된 자원이다. 지금 당장 필요하지도 않은 정보들을 유지하기 위해 값비싼 자원을 낭비할 필요는 없다. 잠시 잊어 버렸다가 필요할 때 기록을 들춰 보..
-
AGGREGATE와 REPOSITORY 5부JAVA/DDD 2021. 1. 8. 19:48
ENTRY POINT와 REPOSITORY 주문은 주문 AGGREGATE의 ENTRY POINT이다. 따라서 주문이 필요한 경우 OrderRepository를 통해 해당 주문 객체를 얻을 수 있다. 그럼 특정한 고객에 대한 주문 목록을 얻어야 한다면 어떻게 해야 할까? 쉽게 생각해 볼 수 있는 방법은 CustomerRepository로부터 고객 객체를 얻은 후 연관을 통해 해당하는 Order 객체들에게 접근하는 것이다. 그러나 이 방법은 Order와 Customer 클래스 간에 양방향 연관 관계를 추가한다. 특정 객체에 속하는 다른 객체들을 조회하는 요구사항마다 양방향 연관 관계를 설정한다면 감당하기 어려울 정도로 모델이 복잡해질 것이다. 고객에 해당하는 주문 목록을 조회하는 적절한 방법은 OrderRe..
-
AGGREGATE와 REPOSITORY 4부JAVA/DDD 2021. 1. 5. 16:39
OrderLineItem은 상품 정보를 알고 있는 책임을 지닌 Product 클래스와 연관 관계를 가지며, 상품의 수량을 속성으로 포함한다. OrderLineItem의 생성자에 전달된 productName은 Product ENTRY POINT를 검색하기 위해 사용하는 검색 키이다. Product은 REFERENCE OBJECT인 동시에 ENTRY POINT이므로 productName을 가지는 Product 인스턴스는 시스템 내에서 유일해야 한다. 따라서 Product를 관리하는 ProductRepository로부터 해당 인스턴스를 얻어 OrderLineItem의 product 속성에 할당한다. getPrice() 메서드는 현재 주문 항목의 가격을 반환하는 메서드로 상품 가격에 상품 수량을 곱한 금액을 반..
-
Aggregate와 Repository 3부JAVA/DDD 2020. 12. 30. 14:18
유창하게(Fluently) 구현하기 AGGREGATE와 ENTRY POINT, REPOSITORY를 사용하여 대략적인 도메인 모델을 만들었다. 이제 테스트 주도 방식을 적용하여 도메인 로직을 개발해보자. 테스트 주도 개발 방식에서는 애플리케이션 코드를 작성하기 전에 실패하는 테스트부터 작성한다. 테스트를 작성할 때는 테스트 대상 객체의 인터페이스가 어떻게 사용될 지를 상상해 보는 것이 중요하다. 테스트 중인 시나리오를 실행하기 위해 객체의 어떤 오퍼레이션을 어떤 순서로 호출하는 것이 효율적인지를 결정한다. 따라서 테스트를 작성함과 동시에 자연스럽게 사용하기 편리한 인터페이스를 설계하게 되는 부수적인 효과도 얻을 수 있다. 객체의 인터페이스 설계와 관련해서 FLUENT INTERFACE라는 방식이 있다. ..