도메인을 모델링할 때 기본이 되는 작업은 모델을 구성하는 핵심 구성요소, 규칙, 기능을 찾는 것이다. 이 과정은 요구사항에서 출발한다.
문서화를 하는 목적은 무엇일까? 바로 지식을 공유하기 위함이다.
실제 구현 코드는 상세한 모든 내용이 담겨 있기 때문에 코드를 보고 전체 소프트웨어를 분석하기에는 너무 많은 시간이 들어간다.
전체적인 기능이라던지 모듈 구조 같은 것들은 코드를 보고 직접 이해하는 것보다 상위 수준에서 정리한 문서를 참고한다면 소프트웨어를 전반적으로 더 빠르게 이해할 수 있을 것이다. => 그렇기에 문서화가 중요함!
전체 구조를 이해하고 더 깊게 이해할 필요가 있을 때 그때 그 부분을 코드로 분석해야 한다.
단순히 구현에 급급한 코드는 문서로서 도움이 되지 않는다. 도메인 지식이 잘 묻어나도록 코드를 작성하지 않으면 코드의 동작 과정은 해석할 수 있어도 도메인 관점에서 왜 코드를 그렇게 작성했는지 이해할 수 없을 것이다.
하지만 코드 자체도 문서화의 대상이 될 수 있다. 단순히 코드를 보기 좋게 작성하는 것뿐만 아니라 도메인 관점에서 코드가 도메인을 잘 표현된다면 코드의 가독성이 높아지고 문서로서 코드가 의미를 가지게 된다.
그렇기에 도메인을 충분히 이해하고 전체 구조에 적용한다면 코드 자체도 소프트웨어를 더 빠르게 이해할 수 있는 문서화로 활용될 수 있을 것이다.(다른 사람이 읽었을 때 이해가 잘 되는 코드가 좋은 코드 아닐까?)
DDD에서 엔티티와 밸류 타입은 도메인 모델의 핵심 구성 요소이다.
고유한 식별자를 가지며 생명주기 동안 상태가 변할 수 있는 객체. 식별자가 같으면 속성이 달라도 같은 엔티티로 취급된다.
public class User {
private UserId id; // 식별자
private String name;
private Email email;
public User(UserId id, String name, Email email) {
this.id = id;
this.name = name;
this.email = email;
}
public void changeName(String newName) {
this.name = newName; // 상태 변경 가능
}
// equals는 식별자만으로 판단
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
return this.id.equals(((User) obj).id);
}
return false;
}
}
식별자가 없고 속성 값으로만 구별되는 불변 객체. 같은 속성을 가지면 같은 객체로 취급된다.
public class Email {
private final String value;
public Email(String value) {
if (!isValidEmail(value)) {
throw new IllegalArgumentException("유효하지 않은 이메일");
}
this.value = value; // 불변
}
public String getValue() {
return value;
}
// 모든 속성으로 동등성 판단
@Override
public boolean equals(Object obj) {
if (obj instanceof Email) {
return this.value.equals(((Email) obj).value);
}
return false;
}
private boolean isValidEmail(String email) {
return email.contains("@"); // 간단한 검증
}
}
참고자료
- 도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지
https://product.kyobobook.co.kr/detail/S000001810495