DDD에서는 private을 지양한다?
객체지향에서는 정보를 감추라고 하는데, 도메인 주도 설계에서는 왜 자꾸 public을 강조할까?
들어가며
객체지향에서는 이렇게 배운다.
- "메서드와 필드는 최대한 감춰라."
- "캡슐화를 통해 객체의 내부 구현을 보호해야 한다."
그런데 도메인 주도 설계(DDD)를 공부하다 보면 이렇게 말한다.
“비즈니스 규칙은 숨기지 말고, 드러내라.”
그럼 결국, private 쓰지 말라는 건가?
헷갈릴 수밖에 없다.
도메인 개념은 감추지 말고 드러내야 한다
스케줄을 체크하는 것은 꽤 중요한 도메인 개념이다.
👉 그래서 다음과 같은 메서드를 외부에 열어주는 게 좋다.
public boolean isSchedulable(LocalDateTime start, LocalDateTime end) {
return isWithinTime(start, end) && isOneHour(start, end);
}
이러면 ReservationService나 Controller에서도 이렇게 물어볼 수 있다.
if (schedule.isSchedulable(start, end)) {
// 예약 가능 → 예약 진행
} else {
// 예약 불가 → 사용자에게 안내
}
의미 있는 도메인 로직이 코드에 드러난다.
병원 예약 시스템에서의 고민
내 도메인 모델 중 하나인 Schedule이다.
public class Schedule {
private final LocalTime startTime;
private final LocalTime endTime;
public void validateSchedule(LocalDateTime start, LocalDateTime end) {
validateTimeInRange(start, end);
validateOneHourUnit(start, end);
}
private void validateTimeInRange(...) { ... }
private void validateOneHourUnit(...) { ... }
}
이 구조는 객체지향적으로는 깔끔하다.
그런데 DDD 관점에서는 아쉬운 점이 있어 보인다.
private 처리된 메서드들을 외부에서 호출할 수가 없다.
그렇다면, 위 코드는 DDD 관점에서 틀린 걸까?
private을 쓰지 말라는 뜻이 아니다
내부 로직은 내부 로직이다.
내부 로직까지 public으로 열 필요는 없다.
정리하자면 DDD에서는 아래 기준으로 접근제어를 생각한다.
목적 | 메서드 예시 | 접근제어자 추천 |
비즈니스 규칙 표현 | isSchedulable, canReserveAt | public |
구현 보조/내부 유틸 | validateTimeInRange, checkHourUnit | private |
비즈니스 의미는 public으로 표현하되, 단순한 구현은 private으로 감춰라.
▼ is~()와 validate~()의 차이 ▼
더보기
is~()는 물어보는 느낌이고, validate은 명령에 가깝다.
어떤 책임을 어디에 둘 것인가를 고민하고 사용하자.
메서드 이름 | 목적 | 부작용 | 주체 | 추천 상황 |
isSchedulable() | 판단만 | 없음 | 호출자 | 조건 분기, UI 제어 |
validateSchedule() | 위반 시 예외 | 있음 | 도메인 객체 | 흐름 제어 없이 검증하고 싶을 때 |
*여기서 쓰인 '부작용'이란 표현은 예외를 터트리는 것을 말한다.
마무리 한 줄 정리
숨길 건 숨기되, 도메인 의미는 숨기지 말자.
'성장 과정 > 인사이트' 카테고리의 다른 글
RESTful API에서 '응답 설계'가 반이라고? (0) | 2025.04.13 |
---|---|
비즈니스 로직이니까 서비스에 있어야지! (1) | 2025.04.09 |
무분별한 Getter & Setter 사용은 OOP 원칙을 위배한다. (0) | 2025.03.27 |