Domain Driven DesignEntityValue Object(값 객체)DTO(Data Transfer Object)Design the infrastructure persistence layerAggregateServiceRepository
Domain Driven Design
- 도메인은 사용자가 어플리케이션을 사용하는 대상 영역. 비즈니스 그 자체. 주문 관리 어플리케이션에서는 주문이 domain, 회계 관리 시스템에서는 회계가 domain
- 객체의 종류 : Entity, ValueObject, DTO, DAO
Entity
- 엔티티는 다른 엔티티와 구별할 수 있는 식별자(primary key)를 가지고 있고 시간이 흐름에 따라 지속적으로 변경이 되는 객체임

Value Object(값 객체)
Java14에 소개된 Record 키워드를 이용하면 VO 쉽게 작성 가능 — https://www.baeldung.com/java-record-keyword
- VO는 point, money, range(start, end) 같은 작은 객체들에 대해 잘 사용할 수 있음. 그러나 큰 객체더라도 conceptual identity가 없거나 프로그램 상에서 참조를 공유해야 하는 상황이 생기지 않을 때에는 VO로 사용이 가능함
- Entity는 id를 통해 구분이 가능하고 얘는 값의 조합으로 구분이 가능함
- eg) Cartesian coordinate (2,3) 을 가지는 객체 두개가 있으면 이 두개의 객체는 같은 객체라고 볼 수 있음. 이러한 객체를 Value Object라고 함
- 값의 조합으로 구분이 가능하기에 똑같은 memory 상에서 똑같은 object를 참조했는지를 신경 쓸 필요가 없음. 그러나 그렇게 함으로써 두개의 객체에 대해 aliasing bug가 발생할 수 있음
Date retirementDate = new Date(Date.parse("Tue 1 Nov 2016")); // this means we need a retirement party Date partyDate = retirementDate; // but that date is a Tuesday, let's party on the weekend partyDate.setDate(5); assertEquals(new Date(Date.parse("Sat 5 Nov 2016")), retirementDate); // oops, now I have to work three more days :-(
- 위와 같은 aliasing bug를 막기 위해 value object 에 대해 중요한 규칙을 부과함 ⇒ value object는 immutable 해야 한다!(immutable object) 값을 변경하기 위해서는 새 객체를 만들어야 함
- 한번 100원 짜리 동전은 영원한 100원 동전임. Entity들이 Value Object를 속성으로 가지고 있음
- 임의의 주문에 대해서 주문자의 이름이 바뀐다던가 하지 않음. 주문자는 쭉 그대로 유지됨
- 배송지, 주문아이템도 그 값이 특정 주소, 특정 아이템을 가리키는 것임. 고유한 값

DTO(Data Transfer Object)
사용 이유, 장점
- remote interface를 사용하고 있을 때, 매번 호출할 때마다 비용이 큼. 그래서 호출 횟수를 줄이기 위해 한번에 데이터에 많은 정보를 가지고 오려고 함. ⇒ 파라미터를 많이 사용하는 것. 그러나 자바에서 함수는 하나의 값만을 리턴해야 하기 때문에, 이때 DTO를 사용
- DTO를 사용하는 주 이유는 multiple remote call → single remote call 로 줄이기 위함임
- 다른 하나의 장점은 직렬화 동작을 감싸는 것.
특징
- DTO는 단순히 데이터 컨테이너임. 로직은 제외하고 데이터만을 가지고 있음.
- 대개 DTO는 object를 layer나 티어 사이에서 전송하기 위해서 사용하게 됨. 단일 어플리케이션에서, 혹은 여러 개의 어플리케이션 사이에서 , JVM 과 JVM 사이에서.
- 불변하는 객체(immutable object)
- VO 또한도 불변객체이지만, DTO와의 차이점은 DTO는 로직이 없고, VO는 로직이 있다는 점임
Design the infrastructure persistence layer

Aggregate
- 일종의 Entity. Entity들의 집합. 각각의 Aggregate에는 Root가 존재하는데 Aggregate Root가 Entity가 되고, Entity들의 집합이 Aggregate가 됨
- Aggregate단위로 트랜잭션이 보장되어야 함. 위의 예시에서 Address가 변하게 되면 Order를 기준으로 커밋이 되야 함.
Service
- 상태를 가지고 있지 않음. 대신 비지니스에서 중요한 프로세스 혹은 비즈니스 룰을 가지고 있는 특정한 행위를 담고 있음 → 메서드만 있음.
- 그 때 각각의 Aggregate를 가지고 트랜잭션을 일으키고 트랜잭션에 대한 보장을 서비스 메서드 혹은 서비스 전체로 할 수 있음
- OrderService는 OrderRepository를 사용하고 Service는 Domain Model Layer에 존재함
Repository
- one repository for each aggregate root
- Order Aggregate를 저장하고 조회하는건 OrderRepository에서만 실행되어야 함
- OrderRepository를 통해 DB 에 저장, 상태 로드
- Entity를 저장하는 저장소
- 위에서 BuyerRepository 와 OrderRepository는 Infrastructure layer에서 알맞는 repository로 구현되게 됨(DB종류 따라)
A repository performs the tasks of an intermediary between the domain model layers and data mapping, acting in a similar way to a set of domain objects in memory. Client objects declaratively build queries and send them to the repositories for answers. Conceptually, a repository encapsulates a set of objects stored in the database and operations that can be performed on them, providing a way that is closer to the persistence layer. Repositories, also, support the purpose of separating, clearly and in one direction, the dependency between the work domain and the data allocation or mapping. — Martin Fowler