1장 - 도메인 모델 시작하기

alsdl0629·2023년 9월 16일
0

도메인 주도 개발

목록 보기
1/2
post-thumbnail

최범균님의 도메인 주도 개발 시작하기를 읽고 관련 내용과 느낀 점을 기록해 보려고 합니다!


도메인이란?

소프트웨어로 해결하고자 하는 문제 영역이다.
ex) 온라인 서점, 주문, 결제 등


한 도메인은 다시 히위 도메인으로 나눌 수 있다.
ex) 온라인 서점에 회원, 주문, 혜택, 배송 하위 도메인


도메인 전문가와 개발자 간 지식 공유

요구사항 = 첫 단추

요구사항 올바르게 이해하지 못하면 요구하지 않은 엉뚱한 기능을 만들게 된다.
그렇게 잘못 개발한 코드를 수정해서 올바르게 고치려면 많은 노력이 든다.
그러므로 개발자는 요구사항을 올바르게 이해하는 것이 중요하다.


요구사항을 올바르게 이해하려면?

개발자와 도메인 전문가가 직접 대화해야 한다.
개발자와 전문가 사이 내용을 전파하는 전달자가 많아 정보가 왜곡되고 손실이 발생하는 걸 방지하기 위함이다.

도메인 전문가, 개발자가 같은 지식을 공유하고 직접 소통할수록 도메인 전문가가 원하는 제품을 만들 가능성이 높아진다.
그러므로 개발자도 도메인 지식을 갖춰야 한다.

Garbage in, Garbage out
“잘못된 값이 들어가면 잘못된 결과가 나온다”
DDD 해석 ➡️ "잘못된 요구사항이 들어가면 잘못된 제품이 나온다."
개발자는 요구사항을 이해할 때 항상 의문을 가지고 왜 이런 기능을 요구하는지 또는 실제로 원하는 게 무엇인지 생각하고 전문가와 대화를 통해 더 나은 제품을 만들 수 있어야 한다.


도메인 모델이란?

특정 도메인(주문, 카테고리, 유저 등)을 개념적으로 표현한 것이다.
도메인 자체를 이해하기 위한 개념 모델이다.
도메인 모델을 사용하면 여러 관계자들이 동일한 모습으로 도메인을 이해하고 도메인 지식을 공유하는데 도움이 된다.

도메인 계층의 객체 모델도 도메인 모델이라고 표현한다.
핵심 규칙을 구현한 코드는 도메인 모델에만 위치하기 때문에 규칙이 바뀌거나 규칙을 확장해야 할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있게 된다. ➡️ SRP 지킴, 응집도 🆙


도메인 모델 추출

아무리 뛰어난 개발자라 할지라도 도메인에 대한 이해 없이 코딩을 시작할 수는 없다.
구현을 시작하려면 도메인에 대한 초기 모델이 필요하다.
도메인을 모델링할 때 기본이 되는 작업은 모델을 구성하는 핵심 구성요소, 규칙, 기능을 찾는 것이다.


엔티티와 밸류

위에서 도출한 모델은 엔티티와 밸류로 구분할 수 있다.
엔티티와 밸류를 제대로 구분해야 도메인을 올바르게 설계하고 구현할 수 있기 때문에 이 둘의 차이를 명확하게 이해하는 것은 도메인을 구현하는 데 있어 중요하다.

엔티티란?

가장 큰 특징은 식별자를 가진다는 것이다
식별자는 엔티티 객체마다 각각 고유하고, 절대 바뀌지 않는다.
위의 정보를 통해 두 엔티티의 식별자가 같으면 두 엔티티는 같다고 판단할 수 있다.

밸류(값 타입)이란?

개념적으로 완전한 하나를 표현할 때 사용한다.
코드의 의미를 더 잘 이해할 수 있도록 한다.

public class Money {
	privat final int value;
    
    // 생성자 & Getter
    
    // 밸류 타입을 위한 기능을 추가할 수 있다.
    // ex) Money 밸류 돈 계산 기능 등
    public Money multiply(int multiplier) {
    	return new Money(value * multiplier);
    }
}

밸류 타입은 불변(생성 후 그 상태를 바꿀 수 없는 객체)으로 구현해야한다.

불변으로 구현해야하는 이유

불변이 아니어서 값을 변경할 수 있다면 객체의 상태를 예측하기 어렵고 바뀐 상태를 파악하기 위해 코드를 살펴보아야 하고, 이는 유지보수성을 상당히 떨어뜨린다.

➡️ 불변은 값이 변하지 않음을 보장받을 수 있기 때문에 예측할 수 있어 안전하게 사용 가능하고, 값이 어디서 변경되었는지 확인하지 않아도 돼서 불필요한 시간을 절약할 수 있다.

도메인 모델에 set메서드 넣지 않기

public class Order {
		public void setXXX(XXX xxx); // 정보를 설정하는 의미
		public void changeXXX(XXX xxx); // 정보를 새로 변경한다는 의미
}

set은 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.
단순히 상태 값을 설정하는 의미만 가진다.

도메인 객체를 생성할 때 온전하지 않은 상태가 될 수 있다.(불완전 상태)

Order order = new Order();

order.setXXX();
order.setXXX();
// 필드 하나 누락(누락할 가능성을 여러두면 나중에 검사하는 코드, 즉 불필요한 코드 작성해야함...)

--------------------------------------

Order order = new Order(xxx, xxx, xxx); // 생성자를 통해 필요한 데이터를 모두 받음

그럼 set은 언제 사용할까?

private void setOrderer(Orderer orderer) {
	if (orderer == null) // 예외 처리
    this.orderer = orderer;
}

set은 접근제한자를 private으로 두어 클래스 내부에서 데이터를 변경할 목적으로 사용하자! (null 체크 등)


도메인 용어와 유비쿼터스 언어

도메인에서 사용하는 용어를 코드에 반영하지 않으면 그 코드는 개발자에게 코드의 의미를 해석해야하는 부담을 준다.
그리고 도메인 용어를 맞추지 않으면 도메인 규칙이 드러나지 않을 수 있다.

코드는 일종의 문서이다.

// Bad
public enum Role {
	ROLE1, ROLE2
}
----------------------
// Good
public enum Role {
	USER, ADMIN
}

유비쿼터스 언어란?

도메인 주도 설계에서 언어의 중요함을 강조하기 위해 유비쿼터스 언어라는 용어를 사용한다.
전문가, 관계자, 개발자가 도메인과 관련된 공통의 언어를 만들고 이를 대화, 문서, 도메인 모델, 코드, 테스트 등 모든 곳에서 같은 용어를 사용한다.
이렇게 하면 소통 과정에서 발생하는 용어의 모호함을 줄일 수 있고, 도메인과 코드 사이에서 불필요한 해석 과정을 줄일 수 있다.


느낀점

2023 인프콘 어느 날 고민 많은 주니어 개발자가 찾아왔다 2탄: 주니어 시절 성장과 고민들에서 영한 님과, 라인 개발자이신 문범우 님께서 개발자는 도메인을 이해하고 도메인 관련 배경지식이 필요하다고 하셨던 말씀이 떠올라 도메인 주도 개발 시작하기를 읽게 되었습니다.

원래 저는 기술에 더 많은 관심이 있었습니다.(개발자는 구현 능력이 중요하다고 생각해서..)

이 책을 읽고 개발자의 역할이 단순한 코드 작성자가 아니라 문제 해결 전문가로서의 모습을 깨닫게 되었습니다. 이를 통해 도메인, 즉 소프트웨어로 해결하고자 하는 문제 영역에 대한 깊은 이해의 중요성을 인식하게 되었습니다.

profile
인풋보다 아웃풋

0개의 댓글