본문 바로가기
도메인 주도 설계

생명주기를 갖는 객체 - 엔티티(Entity)란?

by simplify-len 2020. 10. 28.

엔티티라는 용어는 소프트웨어 개발에서 다방면으로 사용된다. 예를 들면 JPA에서도 도메인을 지정할 때 Entity라는 애노테이션을 붙이고, 어떤 식별자를 가진 객체를 만들때  이를 엔티티라고도 부른다.

물론 ORM과 같은 JPA에서 말하는 JPA와 도메인주도설계에서 말하는 엔티티는 조금 다른 의미를 가진다.

1. 엔티티란?

도메인 주도 설계에서 말하는 엔티티를 설명할 때는 식별성또는 개별성, 동등성 비슷하지만 다른 명칭으로 설명하는데, 여기서 저는 에릭에반스의 저서에서 나오는 식별성으로 엔티티를 설명하고자 합니다.

 어떤 객체를 일차적으로 해당 객체의 식별성으로 정의할 경우 그 객체를 ENTITY라 한다.
ENTITY에는 모델링과 설계상의 특수한 고려사항이 포함돼 있다. ENTITY는 자신의 생명주기동안 형태와 내용이 급격하게 바뀔 수도 있지만 연속성은 유지해야 한다. 또한 사실상 ENTITY를 추적하려면 ENTITY에 식별성이 정의돼 있어야 한다.

ENTITY의 클래스 정의와 책임, 속성, 연관관계는 ENTITY에 포함된 특정 속성보다는 ENTITY의 정체성에 초점을 맞춰야 한다. ENTITY가 그렇게까지 급변하게 변형되지 않거나 생명주기가 복잡하지 않더라도 의미에 따라 ENTITY를 분류한다면 모델이 더욱 투명해지고 구현은 견고해질 것이다.
                                                                                                      -  에릭에반스 p93

엔티티는 생명주기를 갖고, 해당 객체의 식별성으로 정의될 경우 ENTITY라 부릅니다. 이 식별성은 미묘하고 의미있는 속성이므로 절대 Java의 equals와 같은 값으로 구별될 수 있는 것이 아닙니다. 또한 언어에서 제공하는 자동화된 기능으로 대체될 수 없습니다.

 한 객체가 속성보다는 식별성으로 구분될 경우 모델 내에서 이를 해당 객체의 주된 정의로 삼아라. 클래스 정의를 단순하게 하고 생명주기의 연속성과 식별성에 집중하라. 객체의 형태나 이력에 관계없이 각 객체를 구별하는 수단을 정의하라. 객체의 속성으로 객체의 일치 여부를 판단하는 요구사항에 주의하라. 각 객체에 대해 유일한 결과를 반환하는 연산을 정의하라. 이러한 연산의 객체에 유일함을 보장받는 기호를 덧붙여서 정의할 수 있을지도 모른다. 이 같은 식별 수단은 외부에서 가져오거나 시스템에서 자체적으로 만들어 내는 임의의 식별자일 수도 있지만, 모델에서 식별성을 구분하는 방법과 일치해야 한다. 모델은 동일하다는 것이 무슨 의미인지 정의해야 한다.

2. 그렇다면 엔티티의 식별자 생성은 어떻게 해야될까?

  • 사용자는 애플리케이션에 하나 이상의 초기 고유 값을 입력한다. 애플리케이션은 입력한 값이 고유한지 확인해야 한다.
  • 애플리케이션은 내부적 고유성이 보장되는 알고리즘을 사용해 식별자를 생성한다. 라이브러리나 프레임워크가 이를 대신할 수도 있지만, 애플리케이션이 직접 수행할 수도 있다.
  • 애플리케이션이 데이터베이스와 같은 영속성 저장소를 사용해 고유 식별자를 생성한다.
  • 또 하나의 바운디드 컨텍스트(시스템이나 애플리케이션)에서 먼저 고유 식별자를 결정한다. 이 식별자가 입력되거나, 사용자가 여러 선택지 중 하나를 선택한다.

이 부분에 대한 심화된 내용은 반버논의 도메인 주도 설계 책을 참고하시면 좋습니다. 아니면 따로, 이 부분을 정리해서 포스팅하는 시간을 갖도록 하겠습니다.

3. 엔티티의 성질

 엔티티는 속성이 아닌 동일성으로 식별되는 객체입니다.

엔티티를 대표할 수 있는 성질로서

  • 가변입니다.
  • 속성이 같아도 구분할 수 있습니다.
  • 위에서 말하는 식별성을 통해 구별됩니다.

가변입니다.

엔티티는 생애주기를 갖고, 시간이 지남에 따라 나이나 키 등의 속성이 달라지듯이 엔티티의 속성도 변화할 수 있습니다.

속성이 같아도 구분할 수 있습니다.

엔티티는 값 객체와는 달리, 속성이 같아도 구분될 수 있습니다. 가장 흔한 예로 같은 동명이인입니다. 이름이 같다고 해서 같은 사람은 아닌것과 같습니다.

엔티티는 식별자로서 구별됩니다.

식별성

식별성은 나와 비슷한 객체들 사이에서 구분될 수 있는 유일한 값입니다.

즉, 엔티티는 위 3가지의 특징을 가집니다. 

또한 엔티티는 값 객체가 되면서 엔티티가 될수도 있습니다. 

타이어를 예로 들면, 타이어는 자동차를 구성하는 한 부품입니다. 특성에는 세세한 차이가 있어도 서로 바꿔 쓸 수 있으므로 값 객체로 나타내기에 적합한 개념입니다. 그러나 타이터를 만드는 공장이라면? 그 타이어가 언제 만들어졌는지 등 개체를 식별하는 것이 중요합니다. 여기서의 타이어는 엔티티로 나타내는 것이 더 적합합니다.

4. 엔티티를 정의내릴 때 장점으로는?

엔티티의 식별성과, 상태는 자기 서술적인 코드가 된다.

엔티티내에서 유효성검사와 같은 행위는 해당 엔티티가 어떤 역할을 수행하고, 규칙을 가지고 있는지 표현해주기 때문에 자기를 표현해주는 코드가 됩니다.

도메인에 일어난 변경을 코드에 반영하기 쉽습니다.

소프트웨어 세계에서 요구사항은 무궁무진하게 변화됩니다. 그런 과정속에서 어떻게 더 확장성있는 코드를 짜야하는 것은 개발자의 몫입니다. 순간순간 변화되는 요구사항에서도 비교적 손쉽게 변화를 반영시키기 위해서는 엔티티의 역할이 중요합니다.

객체지향은 현실에 일어난 세계를 닮는다고 했습니다. 만약 사람이 나이를 먹게되면, 사람이라는 객체의 age만 커지면 됩니다.

즉, 큰 변화가 없이 엔티티가 불리는 객체를 변화시켜주면됩니다.

마무리

지금까지, 엔티티에 대해서 알아봤습니다. 엔티티라는 것에 대한 개념은 쉽다고 생각합니다. 그러나, 진짜 어려운건 내가 이 객체를 엔티티로 놓는가, 값 객체로 놓는가? 의 문제와 만약 엔티티로 놓는다면- 식별자는 어떻게 가져가야할까? 라는 고민이 또 생깁니다. 이렇든 엔티티라는 것은 쉬운게 아니라고 생각합니다.

다음에는 값 객체에 대해서 알아보도록 하겠습니다.

댓글