TSS에는 종종 흥미있는 기술 논쟁이 벌어진다. 가끔 자기가 좋아하는 프레임워크나 기술에 편먹고 빠순이들 수준으로 감정싸움 하는 것도 있기는 하지만.. ㅋㅋ.

보통 논쟁이 지속 되는 이유는 어느 한쪽의 주장이 일방적으로 옳지만은 않기 때문이다. 좀더 구체적인 context에서가 아니라면 어느쪽의 승리를 쉽게 단정하기 어려운 주제를 각각 편에서서 자기의 context에서 논쟁을 벌이다 보면 결론은 빨리 나지는 않지만 대신 각각의 주장에 담긴 여러가지 생각들과 지식을 많이 얻어낼 수 있어서 좋은 면이 있다. 금새 본전이 다 드러나기 때문이다.

Cameron Purdy의 An interesting topic 을 통해서 발견한 Protecting the Domain Model은 그런 좋은 논쟁의 하나라고 보여진다.

이 글에서 다루고 있는 내용은 사실 그동안 많이 이야기 되왔던 것이다. 바로 Domain Model과 DTO의 사용에 관한 것이다.

DTO(예전에는 VO로 더 많이 불렸었다)는 대표적인 pattern과 anti-pattern 양쪽에 다 등장하는 디자인 패턴중의 하나이다. DTO가 초기에 design pattern으로 인기를 얻은 것은 coarse-grained 방식의 EJB 접근법이 한창 주가를 올리던 EJB의 절정기였던것으로 기억한다. EJB client가 fine-grained된 방식으로 remote call을 EJB component에 자꾸 보내는 것은 매우 많은 부하를 주고 리소스를 낭비한다는 지적아래 Entity bean을 client로 직접 노출하는 것은 기본적으로 피하고 session bean(주로 session facade)을 통해서 Entity bean의 정보를 DTO구조의 클래스를 사용해서 정보를 카피해서 한번에 client에 전송하고 전송받는 방식이 가장 대표적인 EJB best practice로 제시되왔다.

사실 DTO가 사용된 이유는 Entity bean을 serialize해서 client로 보낼 방법이 없었기 때문이다. 거의 비슷한 setter/getter를 가진 DTO를 Entity bean과 별도로 만들고 일일히 프로퍼티를 카피해주는 그런 코드들을 사용할 수 밖에 없었다. 솔직이 짜증나는 짓이었다. 물론 좀 편하게 reflection등을 이용해서 bean property를 카피해주는 기술도 사용되었지만 성능상의 문제로 인해 사용이 기피되기도 했다.

그 후에 세월이 지나고 EJB가 인기가 떨어지고 대안 기술들이 나오기 시작하면서 DTO 무용론이 제기되기 시작했다. DTO는 쓸데없이 프로그램을 지저분하게 하는 패턴이라서 사용을 자제해야 한다는 것이었다. DTO는 anti-pattern이라는 주장인데 그런 면에서 가장 큰 목소리를 내었던 것은 POJO기반의 Domain Model을 지원하는 Hibernate와 ORM쪽이었다.

Hibernate는 완벽한 POJO베이스의 Domain Model들을 사용할 수 있게 해주기 때문에 그 Domain Model오브젝트를 구지 DTO로 카피해서 사용할 것 없이 바로 비즈니스 로직 티어나 View, Controller등으로 보내서 사용하도록 하는 것이다. 이것이 바로 Domain Model Everywhere라는 사용방식이다.

더 나아가서 ActionForm같은 잘못 설계된 폼데이터 클래스를 사용하지 않아도 되는 (그래서 구지 DTO를 써야 하게 만들지 않아도 되는) WebWork이나 SpringMVC에서는 Form데이터를 바로 Domain Model 오브젝트로 받아서 사용하게 됨으로 해서 Domain Model오브젝트 하나가 Form Data Obejct -> Business Logic Parameter -> Persistent Model Object -> Business Logic Return Value -> Model Object in View 라는 형태로 변신할 수 있게 되었고 진정한 Domain Model Everywhere라는 목표를 이룰 수 있게 되었다. 여기에는 Hibernate의 Domain Model오브젝트가 Detached Object <-> Persistent Object로 자유롭게 변신할 수 있는 기능과 SpringMVC의 custom property editor를 이용해서 HTTP FormData <-> Domain Object사이의 binding을 원활하게 해줄 수 있는 기능등이 큰 역할을 했다고 볼 수 있다. 게다가 Spring의 OpenSessionInView strategy는 persistent상태에 있는 domain model을 그대로 view에 전달함으로 view내에서 object graph를 따라서 원하는 정보를 lazy-loading방식으로 가져올 수 있게 했다.

이렇게 해서 DTO는 사라질 운명을 맞이해야 할 것 같지만 사실 여전히 DTO는 많이 사용되고 있고 오히려 Domain Model Everywhere방식의 문제점을 지적하고 다시 DTO를 적극적으로 사용해야 한다는 주장들이 나오고 있다. TSS에 올라온 메인 글에 인용된 글의 저자가 그러한 주장을 하고 있는 대표적인 사람으로 보인다.

DTO를 써야한다고 주장하는 이유는 여러가지가 있다.

일단 Domain Model은 순수하게 Domain Logic만 가지고 있어야하지 Presentation Logic을 가지고 있어서는 안된다는 것이다. 사실 Domain Model을 아무리 잘 설계했다고 해도 각 view내에서 domain model의 getter만을 이용해서 원하는 정보를 표시하기가 어려운 경우가 종종 있다. 이런 경우 Domain Model내에 presentation을 위한 필드나 로직을 추가하게 되는데 이러한 방식이 모델링의 순수성을 깨고 Domain Model오브젝트를 망가뜨리게 된다는 것이다. 또 Domain Model을 복잡하게 조합한 형태의 presentation요구사항들이 있기 때문에 Domain Model을 직접사용하는 것은 불가능하기도 하다는 것이다.

또 Domain Model의 setter가 view, controller등으로 노출 됨을 통해서 악의적인(?) client가 Domain Object데이터를 망칠 수 있다는 것이다.

또 여러가지 이유가 있지만 가장 큰 이유는 역시 Domain Model과 Presentation Model의 갭이 있기 때문이라는 점이다. 그부분을 DTO가 담당해줘야 하기 때문에 DTO를 사용해야 한다는 것이다. EJB시절의 DTO와는 좀 이유가 달라지기는 했다.

그런데 DTO를 사용해야 한다는 쪽에서도 그 사용전략면에서 상당히 다양하게 갈리는 것을 볼 수 있다.

우선은 DTO를 Domain Model을 복사한 형태에다가 다양한 presentation logic을 추가한 정도로 사용하는 것이다. Domain Object는 Persistent만을 위해서 사용하고 일단 presentation logic tier로 넘어오게 될때는 DTO의 모습으로 바껴서 오는 것이다. 반대도 마찬가지고.

또 어떤 사람들은 DTO를 interface기반으로 작성한다. 이때 interface는 각 presentation(view)의 필요한 내용에 따라 작성이 되면 그 뒤에 Domain Model Object를 배치하는 방식이다. 그래서 어떤 경우에는 DTO per View로 작성되기도 한다.

또 다른 경우는 Domain Model + DTO 방식을 사용하는 것이다.
바로 내가 쓰는 방식이다.

나는 SpringMVC + SpringIoC + Hibernate기반의 프레임워크 구조를 사용한다. 따라서 기본적으로는 Domain Model Everywhere를 지향한다. 또 약간 꺼림직 하기는 해도 Domain Model안에 presentation logic을 넣는다. 사실 presentation logic이라고 하기는 하지만 어떻게 생각하면 Domain Logic이라고 볼 수도 있다. Domain의 정보를 여러 형태로 가공해서 data형태로 제공하는 것을 구지 presentation logic이라고 볼 수 없기 때문이다. 최종적으로는 View에서 사용하기 위해서 만들어졌기는 하지만 Domain의 정보를 제공한 측변에서 보자면 단지 도메인 정보로직일 뿐이기 때문이다. 또 진정한 presentation logic은 view내에서 별도로 구현하기 때문이다. 다만 Domain object가 Hibernate persistent POJO이기 때문에 persistent field와 transient field가 동시에 사용되고 있는 점만 조심하면 될 뿐이다.

내 경험으로 보자면 기본적으로 Domain Model Object는 모든 tier를 관통하면서 사용되어지면서 각 tier에서 독자적인 모습(독립적인 양태)으로 노출되는 것이 맞다고 생각한다. Domain Model Object가 POJO라는 점이 그런면에서 큰 의미가 있다고 본다. Presentation TIer에서는 그 POJO의 getXXX가 직접적인 persistent field인지 로직에 의해서 가공된 정보인지는 중요하지 않다고 본다. 다만 그 Domain Model Object를 통해서 자신이 원하는 정보를 얻거나 쓰면 그만일 뿐이다.

하지만 Domain Model Object의 구조와는 매우 다른 형태의 presentation logic을 위해서나 또는 persistent data가 아닌 정보를 viwe에 보내야 할 때는 기꺼이 DTO를 만들어서 사용한다. 앞에서도 얘기한 것처럼 view에서는 그것이 DTO인지 Domain Model인지 “알께 머람” 이기 때문이다.

Domain Model Everywhere + DTO전략은 현재 내가 생각하는 가장 이상적인 방식이다. 하지만 one-size-fits-all 방식이라고 하고 싶지는 않다. 이 부분은 그때 그때 달라요에 해당하는 것이라고 본다. Hibernate가 모든 종류의 프로젝트와 애플리케이션에 다 적합한 것이 아니듯이 어떤 경우는 DTO기반으로 작성하는 것이 옳을 때도 있다. 하지만 기본적으로 Hibernate를 사용하고 그에 따른 Domain Model이 적절하게 설계되어 있다면 지금 제시한 방법이 가장 이상적이지 않을까 생각해 본다. 한가지 주의 할 것은 이 경우 Persistent Model과 Domain Model의 차이가 있을 수 있다는 것이다. 하지만 Hibernate의 철학대로 OO에서의 모델이 반드시 RDB의 모델과 일치할 필요는 없다.

좀 더 고민해봐야 할 주제들은. AOP를 이용해서 Domain Model을 확장하는 기술과 Abstract Domain Model이나 Interfrace기반의 Domain Model방식이다. 이중에서 AOP는 여러가지 새로운 가능성을 보여주고 있는듯 하다.

사실 이런 주제는 구체적인 예(설정)와 코드를 가지고 얘기하는 것이 바람직하다. 왜냐면 DTO vs Domain Model에는 그 결론에 영향을 미치는 다른 많은 요소와 조건들이 있기 때문이고 그것은 구체화된 케이스를 가지고 하지 않으면 논리적인 비교가 어렵기 때문이다. Presentation Logic이 머가 어쨌길래 Domain Model이 안되는거야? 하면 예를 들어서 보여줘야 할 것이 아닌가. 그리고 그런 예가 일반화 되어서 실제 real-world에서 많이 발생하는 것인지 또 다른 대안은 없는지 논의가 가능하리라 본다. Rod Johnson처럼 전방위적으로 모든 종류의 장단점을 나열하고 치밀하게 분석해 내는 능력이 없다면 말로만 이런 주장을 펼치는 것은 사실 매우 힘든 작업이 될 수도 있다. (사실 이런 논쟁이 붙었을 때 가장 쉬운 방법은 DTO꼬져요. 요즘도 그런거 쓰는 사람이 있나? 라고 해서 상대방의 기를 팍 죽이고 뭔가 자신이 알고 있는 지식이 문제가 있는지 의심이 가도록 해서 꼬리를 내리게 하는 방식이다. 생각보다 어설픈 지식을 가진 자칭 전문가들이 이런류의 답변을 많이 하는데… 기회가 되면 한번 붙어보고 싶다.)

Related posts:

  1. Eternity님의 Domain-Driven Design의 적용 시리즈
  2. TSE2006 넷째날 두번째 세션 – ROO
  3. 뒤늦게 쓰는 SpringOne 2007 셋째날 후기
  4. EJB3의 Pluggable Persistent Component
  5. Maven POM에 attribute 사용하기 (2)
  6. 이번주 계획과 이것 저것
  7. SpringDM과 차세대 OSGi
  8. 기본에 충실하자? OO가 중요하다?
  9. Spring 3.0 @MVC 메소드에서 자동으로 리턴 모델에 추가되는 것들
  10. 지난주 스프링포럼 질문 몇개

Facebook comments:

to “Domain Model vs. DTO”

  1. Does your site have a contact page? I’m having a tough time locating it but, I’d like to shoot you an email.

    I’ve got some creative ideas for your blog you might be interested in hearing.
    Either way, great blog and I look forward to seeing it expand over time.

  2. Wow, amazing weblog format! How lengthy have you been running a blog for?
    you make blogging look easy. The entire look of your site is excellent, as neatly as the content material!

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha