Spring MVC

springmvc.egloos.com


포토로그


2012/05/19 04:39

Entity와 Value Object Domain Driven Design

사실 이 두가지 개념을 어떻게 풀어 나가야 할지 참으로 난해하다. 왜냐하면 'Entity'와 'Value Object'는 개발자가 어떤 관점에서 바라보느냐에 따라 이리도 될 수 있고 저리도 될 수 있는 참 모호한 개념이기 때문이다.

Entity

일반적으로, entity란 존재하는 것, 즉 실체를 의미한다. 이 용어의 어원은 라틴어의 ens에서 나왔으며, 사물의 존재와 그것의 품질 사이에 구별을 짓는다. entity가 되기 위해 필요한 일은, 그저 존재하는 것이 전부이다. 어떤 것이 존재한다는 사실은, 그것이 다른 존재나 entity로부터 분리되어있음을 암시하는 듯하다. 프로그래밍이나 공학에서, 그리고 아마도 많은 다른 상황들에서, 이 용어는 명확한 사물이든, 이름이 붙여져 있지 않은 추상화된 아이디어든 관계없이 단일체를 인식하는데 사용된다.


굉장히 비슷한 성격을 갖고 있는 두 개념이기에 우선 공통부분을 살펴보고 왜 'Entity'와 'Value Object'가 구분될 수 있는지 살펴보자. 우선 'Entity'와 'Value Object'는 둘다 서비스 내에서 유일함을 인정받는 오브젝트이며 정확히 구분될 수 있는 식별성을 갖고 있다. 그리고 둘 다 하나 이상의 속성을 가질 수 있으며 이러한 고유 상태값은 데이터베이스에 기록되어 보존할 수 있다.

그 뿐만이 아니다.'Entity'와 'Value Object'는 서로가 서로를 참조하는 집합체가 될 수도 있는데, 'Entity'가 'Value Object'를 감싸안은 'AGGREGATE'(집합체)가 될 수도 있고 반대로 'Value Object'에서 'Entity'를 참조할 수도 있다.
이렇게만 놓고 본다면 둘은 굉장히 비슷한 성격을 가지고 있는데다 그 역할이 거의 흡사해, 구분 짓는 것의 의미가 없어보일지도 모른다. 실제로 많은 개발자들이 빈약한 도메인 오브젝트를 일괄적으로 'VO'라는 네이밍('Value Object'의 줄임말)을 짓는 것을 보면 이런 구분을 잘 이해하지 못하는 경우도 비일비재한 듯 싶다.

물론 빈약한 도메인을 활용하는 'MVC' 아키텍쳐에서 굳이 'Entity'와 'Value Object'를 구분지어줄 필요는 없으므로 불필요한 성격분류를 할 필요는 없다. 다만 도메인 주도 설계에 큰 관심이 있고 실제로 서비스에 적용해보고자 할 때에는 둘의 성격을 반드시 구분지어줄 필요가 있다.

Value Object

'ValueObject'는 'J2EE'의 패턴 중 하나로 일정한 입력값을 정리하여 보관 및 유지해 두는 오브젝트이다. J2EE 패턴에서는 'Trasfer Object'라고도 하는데 본래에는 'EJB'에서 원격 메소드 호출의 회수를 줄임과 동시에 퍼포먼스의 저하를 막는 목적으로 개발된 패턴이다.

그렇다면 본격적으로 둘의 성격이 어떻게 구분지어질 수 있는지 살펴보자. 궁극적으로 둘의 성격은 하나의 조건으로 정확하게 분리될 수 있는데 그 조건은 다름 아닌 연속성이다. (연속성이란 식별 가능한 오브젝트의 속성들이 필요에 따라 변경될 수도 있다는 것을 의미한다.)

보다 빠른 이해를 위해 카페에서 커피잔을 들고 있는 한 남자를 상상해보자. 우리는 이 남자와 커피잔 모두 구분지어 질 수 있는 (식별성을 가진) 오브젝트가 될 수 있다는 사실을 알 수 있다. 여기서 너무 디테일한 시간적인 연속성은 제외하고 남자와 커피잔을 코드 상 오브젝트라 인지하면서 바라보았을 때, 남자라는 오브젝트는 입고 있는 옷이라던가 헤어스타일, 기분 같은 것들이 지속적으로 변경될 수 있다는 점을 알 수 있다.

반대로 우리는 커피잔이라는 오브젝트가 변할 수가 없다는 사실 또한 알고 있다. (물론 '변할 수 있다'라는 주장도 가능하다. 일단 필자의 이야기를 끝까지 들어보자!) 커피잔이라는 오브젝트는 커피잔 자체가 사라지고 새로운 커피잔 오브젝트가 등장하지 않는 우리가 앞서 생각했던 커피잔이 변경될 소지는 거의 없다.

그러므로 우리는 여기서 연속성이라는 성격으로 두 오브젝트, 남자와 커피잔의 성격을 분리할 수 있게 되었다. 남자라는 오브젝트는 연속성을 가지고 있으므로 우리는 실체가 존재한다하여 'Entity'라고 정의할 수 있다. 그리고 커피잔은 변경될 수 없는 불변의 가치를 가지고 있으므로 'Value Object'라고 부를 수 있다.

문제는 이러한 관점이 극히 주관적이라는 것이다. 만약 당신이 이 커피잔을 시간이 흐름에 따라 부식되는 상태를 표현한다거나 담겨있는 커피 양의 차이를 세밀하게 표현하고자 하는 이유를 들어 커피잔을 'Entity'라 주장할 수도 있다! 그리고 이러한 이유는 상황에 따라 매우 타당하게 받아들여질 수 있을 것이다.

결론적으로 보자면 위와 같은 분류가 가능했던 까닭이 단지 필자가 전체적인 상황을 남자라는 오브젝트를 중심으로 이해했기 때문에 커피잔이 'Value Object'가 됬을 뿐, 실상 둘다 'Entity'가 될 수도 있고 'Value Object'가 될 수 있다.

그렇다면 두 오브젝트는 도대체 어떻게 분리해야 할까? 이것은 어디까지나 설계자 스스로의 역량이다. 사물의 본질을 잘 이해하고 이것이 변하지 않는 고유의 성질을 갖고 있다면 설계자 스스로가 판단하여 'Value Object'로 분류하면 되고 연속성을 가지고 있다면 'Entity'로 분류하면 된다.

가끔 설계 단에서 하나의 오브젝트를 놓고 'Entity'와 'Value Object'를 구분짓는 논쟁이 벌어지곤 하는데… 솔직히 이건 정말 무의미한 소모전이다. 왜냐하면 대부분의 경우, 서로 주장하는 이유가 맞는 말이기 때문이다. 아마 역사상 '엄마가 좋아 아빠가 좋아' 질문 다음으로 가장 짜증나고 답답한 논쟁이라고 생각해도 될 것이다.

혹여나 개발자 사이에서 이러한 논쟁의 시비가 붙는다면 일단 서로의 이유는 잠시 접어두고 서비스의 성격만 고려하여 결론짓는 것이 가장 유리하다. 괜히 앞으로 있지도 않을 디테일한 성격을 들어 이것을 'Entity'라 지정할 필요도 없고 너무 값을 'static'하게 가져가려고만 해서도 안된다. 이런 성격의 분리는 서비스의 성격만 고려하더라도 분명한 결론에 도달할 수 있다.

마지막으로 기술적인 이야기만 짤막하게 하고 넘어가자면 'Value Object'는 연속성을 가지지 않는 오브젝트이므로 내부 프로퍼티를 final로 지정하여 변경을 불가하는 것이 좋다.



덧글

  • 회멸 2012/07/09 09:52 # 삭제 답글

    좋은 개념 알아갑니다
    감사합니다 =)
  • 장호 2014/04/21 17:20 # 삭제 답글

    우와 글이 정말 레전드급이에요
  • MJ 2015/10/09 12:06 # 삭제 답글

    VO(Value Object) 도 식별성을 가지는 것이 (즉 유일성) 오히려 헷갈립니다.
    RO(Reference Object) 의 특성이 유일성과 연속성이고, VO 는 단순 값을 저장하기 위한 용도이며 값이 같으면 같은 객체로 보는 동등성(equals)과 불변성을 특징으로 같기 때문에 RO와 VO를 구분하는 기존은 "연속성" 뿐 만 아니라 "유일성"도 포함되지 않나요?
  • MJ 2015/10/09 12:12 # 삭제 답글

    우선 'Entity'와 'Value Object'는 둘다 서비스 내에서 "유일함"을 인정받는 오브젝트이며 정확히 구분될 수 있는 식별성을 갖고 있다. 그리고 둘 다 하나 이상의 속성을 가질 수 있으며 이러한 고유 상태값은 데이터베이스에 기록되어 보존할 수 있다.

    중간에 유일함에 대한 댓글이었습니다.

    RO는 동일성(==)기반으로 식별하고 VO는 동등성(equals) 기반으로 식별되기 때문에 오해의 소지가 있다고 봅니다.
댓글 입력 영역