DDD
DDD란
도메인 주도 설계로, 도메인의 모델과 로직에 집중하는 설계 방식
데이터 주도 설계
객체가 포함하고 있는 데이터를 조작하는데 필요한 행동을 정의하고 이를 중심적으로 설계하게 된다.
객체가 수행할 책임이 아니라 상태에 초점을 맞추어 코딩을 하게된다.
그래서 캡슐화의 원칙을 위반하게 된다.
따라서 데이터 주도 설계에서 탈피해서 순수한 도메인의 모델과 로직에 집중하자는 것이 DDD 설계 방식이다.
용어 정리
- 유비쿼터스 랭귀지 : 모든 사람이 사용하는 공통의 언어를 말하며, 정확하고 일관적으로 표현되는 단어나 문장을 말한다.
- 도메인 : 해결하고자 하는 문제
- 도메인 모델 : 문제를 개념적으로 표현한 것
- Entity : 테이블 모델
- Value Object(VO) : 불변 타입 객체로 일관성을 유지하기 위해 사용
- Aggregate : 엔티티와 VO의 묶음
- Root Aggregate Entity: 중심이 되는 엔티티라고 하며, 엔티티들의 연관관계에서 모든 책임을 지는 엔티티를 말한다.
중요한 점
불필요한 중복을 피하고 애그리거트 루트를 통해서만 도메인 로직을 구현하게 만들려면 두 가지 습관이 있어야 한다.
- 단순히 필드를 변경하는 setter를 public 범위로 만들지 않는다.
도메인 로직이 응용 계층이나 표현 계층으로 분산되지 않도록 방지하는 역할을 한다. set 형식 이름 말고 cancel이나 changePassword처럼 의미가 더 잘 드러나는 이름을 사용할 빈도가 높아진다. - VO(Value Object)은 불변으로 구현한다.
VO가 불변이면 VO의 값을 변경하는 방법은 새로운 VO를 전달해서 값을 변경하는 방법밖에 없도록 하여 일관성을 유지한다.
클래스의 메서드를 통해 객체의 상태를 변경하고 있으며, 값 객체를 불변으로 구현하기 위해 새로운 객체를 반환해야한다.
기존의 값을 변경하는 대신, 변경된 값을 가진 새로운 인스턴스를 반환하는데, 이렇게 하면 기존의 값 객체는 변경되지 않고, 새로운 값 객체가 생성되어 일관성을 유지할 수 있게된다.
=> 엔티티간 결합도를 낮춘다.
다른 엔티티를 수정할 필요가 없고 유지보수가 편해지기 때문에 사용 추천
아키텍처(nest.js 프레임워크)
interface layer
- interface, DTO, Controller
Application layer
- service
Domain layer
- entity(model)
Infrastructure layer
- repository
Layered Architecture 규칙
- 상위 계층이 하위 계층을 호출하는 단방향성을 유지한다.
- 상위 계층은 하위의 여러 계층을 모두 알 필요없이 바로 밑의 근접 계층만 활용한다.(interface -> application, application -> Domain 과 같이)
- 상위 계층이 하위 계층에 영향을 받지 않게 구성해야 한다. (중간 계층을 기준으로)
- 하위 계층은 자신을 사용하는 상위 계층을 알지 못하게 구성해야 한다.
- 계층 간의 호출은 인터페이스를 이용한다. (구현 클래스에 직접 의존하지 않음으로써 약한 결합을 유지해야 한다.)
도메인 계층의 입장에서 이런 식으로 구현을 하게 되면 인프라 스트럭처 계층의 변화에 따라서 도메인 계층의 구현이 영향을 받게 된다. 그래서 DIP(의존성 역전)를 이용하여 도메인 계층에서 정의한 인터페이스를 인프라스트럭처에서 구현 하는 식으로 설계한다.
도메인 계층에 비즈니스에 대한 해석을 보관하여 엑기스로 만들어 놓고, 나머지 3개의 계층에서 사용하는 방식이다. 이렇게 구조를 가져가게 되면 도메인 모델의 구현체에 최소한의 영향을 주면서 확장이나 개선이 가능해진다. 또한 비즈니스 로직이 아닌 프로그램 구동에 필요한 군더더기 소스코드들이 인프라스트럭처 계층으로 빠지기 때문에, 도메인 모델이 표현된 코드의 가독성을 높일 수 있다는 장점이 있다.
https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd
https://dev-coco.tistory.com/166