도메인 주도 설계(DDD)에서 Entity와 Value Object는 핵심적인 개념들입니다.
이 두 개념은 객체지향 프로그래밍에서 매우 중요하지만, 종종 혼동되거나 잘못 사용되기도 합니다.
이 글에서는 Entity와 VO의 근본적인 차이점과 각각의 개념을 언제, 어떻게 사용해야 하는지 알아보겠습니다.
Entity(엔티티)란?
엔티티는 고유한 식별자(ID)를 가지고 있으며, 그 속성이 변경되어도 동일한 객체로 인식되는 도메인 객체입니다.
주요 특징
- 식별성(Identity): 고유한 ID로 구별됩니다.
- 가변성(Mutability): 시간이 지남에 따라 속성이 변할 수 있습니다.
- 생명주기(Lifecycle): 생성, 변경, 삭제 등의 생명주기를 갖습니다.
- 동등성 비교: 식별자를 기준으로 동등성을 판단합니다(두 엔티티는 모든 속성이 같아도 ID가 다르면 다른 객체).
엔티티의 예
- 사용자(User)
- 주문(Order)
- 상품(Product)
- 계정(Account)
VO(Value Object, 값 객체)란?
값 객체는 식별자가 없으며, 객체의 속성 값 자체가 그 정체성을 결정하는 객체입니다.
주요 특징
- 식별성 없음: 고유한 ID가 없습니다.
- 불변성(Immutability): 생성 후 속성을 변경할 수 없습니다.
- 값 자체가 중요: 객체가 가진 값 자체가 의미를 가집니다.
- 동등성 비교: 모든 속성이 같으면 동일한 객체로 간주됩니다.
값 객체의 예
- 주소(Address)
- 금액(Money)
- 날짜 범위(DateRange)
- 좌표(Coordinate)
- 이메일(Email)
Entity와 VO의 핵심 차이점
특성 | Entity | VO |
---|---|---|
정체성 | ID로 구별됨 | 값으로 구별됨 |
가변성 | 가변적 | 불변적 |
동등성 | ID가 같으면 동일 | 모든 속성이 같으면 동일 |
생명주기 | 있음 | 없음(소유 객체에 종속) |
핵심 질문 | "누구인가?" | "무엇인가?" |
비유로 이해하기
Entity와 VO의 차이를 쉽게 이해하기 위한 비유를 들어보겠습니다
- Entity는 사람과 같습니다: 사람은 이름이나 외모가 변해도 같은 사람입니다. 주민등록번호(ID)로 식별됩니다.
- VO는 돈과 같습니다: 1만원권 지폐는 개별 지폐의 일련번호가 중요한 것이 아니라, 그 가치(1만원)가 중요합니다. 같은 금액의 지폐는 서로 대체 가능합니다.
예시 코드로 알아보기
Entity 예시 (Kotlin)
class User(
val id: UUID,
var name: String,
var email: String
) {
fun changeName(newName: String) {
this.name = newName
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as User
return id == other.id
}
override fun hashCode(): Int {
return id.hashCode()
}
}
위 코드에서 User
엔티티는 아래와 같은 특성을 갖습니다.
- 고유한 ID를 가집니다.
- 이름을 변경할 수 있습니다(
changeName
메서드). - 동등성 비교(
equals
)가 ID만으로 이루어집니다.
VO 예시 (Kotlin)
data class Money(
val amount: BigDecimal,
val currency: Currency
) {
fun add(other: Money): Money {
require(this.currency == other.currency) { "Currency mismatch" }
return Money(this.amount.add(other.amount), this.currency)
}
// data class는 equals와 hashCode를 자동으로 구현합니다.
// 모든 프로퍼티를 기반으로 동등성을 비교합니다.
}
위 코드에서 Money
값 객체는 아래와 같은 특성을 갖죠.
- 식별자(ID)가 없습니다.
- 불변이며, 값을 변경하려면 새 객체를 생성합니다(
add
메서드). - 모든 속성(amount, currency)이 같으면 동일한 객체로 간주합니다.
실무에서의 적용 방법
Entity를 사용해야 할 때
- 객체를 추적하고 생명주기를 관리해야 할 때
- 시간에 따라 상태가 변하는 객체일 때
- 고유하게 식별해야 하는 객체일 때
VO를 사용해야 할 때
- 개념적으로 하나의 완전한 값을 표현할 때
- 불변성이 필요할 때
- 여러 속성을 묶어 새로운 개념으로 만들 때
- 수량, 측정값, 설명 등을 표현할 때
결론
Entity와 VO는 도메인 모델링의 기본이 되는 중요한 개념입니다.
이 둘의 핵심적인 차이는 '정체성(Identity)'에 관한 것입니다.
Entity는 고유한 식별자를 통해 "누구인가?"를 중요시하고, VO는 객체의 속성 값을 통해 "무엇인가?"를 중요시합니다.
이 두 개념을 올바르게 이해하고 적용하면 더 명확하고, 유지보수하기 쉬운 도메인 모델을 설계할 수 있습니다.
또한 불필요한 복잡성을 줄이고, 도메인의 의도를 코드에 더 잘 반영할 수 있습니다.
적절한 상황에서 올바른 개념을 선택하는 것이 중요하며, 이는 시스템의 품질과 유연성을 크게 향상시킵니다.
728x90
'개발 방법론' 카테고리의 다른 글
아 글쎄 제 의도는 그게 아니었다니깐요?! - 하이럼의 법칙 - (0) | 2025.03.31 |
---|---|
헥사고날 아키텍쳐(feat. 코틀린 멀티 모듈) (1) | 2023.11.20 |
바운디드 컨텍스트(Bounded Context)와 애그리게이트(Aggregate)의 차이 (0) | 2023.11.13 |
데이터베이스 트랜잭션이 둘 이상의 애그리거트 인스턴스를 수정하지 못하게 하라! (1) | 2023.11.12 |
비즈니스 요구사항 증가에 따른 애그리게이트 분리 (1) | 2023.11.12 |