왜 DTO (데이터 전송 개체)가 안티 패턴입니까?


132

최근에 사람들 은 DTO ( 데이터 전송 개체 )가 안티 패턴 이라고 말합니다 .

왜? 대안은 무엇입니까?


11
아마도 비즈니스 객체 자체가 자체 데이터를 전송할 수 있기 때문에 대단히 감사합니다!
Zoidberg

13
"반 패턴"은 "15 분 전에 오래 사용 된 문구"에 대한 나의 후보 일 수 있습니다. "그것은 것을 ... 잘 알려져있다"것처럼, 지금 "나는 내 생각을 정당화 귀찮게 걱정하지 않는다"와 동의어이다
크레이그 Stuntz

6
Zoidberg는 유선으로 메소드를 사용하여 객체를 전송하여 CORBA, DCOM 및 기타 기억을 지우려고했던 경험을 제공했습니다. 문제는 조만간 사람들이 그 메소드 를 호출 하기를 원한다는 것 입니다.
Craig Stuntz

10
DTO들은 불행히도 J2EE에서 약자 DRY 원칙을 구체화 할 일의 반복 자신을.
joeforker

당신은 이것을 읽을 수 있습니다 : 데이터 전송 객체는 수치입니다
yegor256

답변:


139

일부 프로젝트에는 모든 데이터가 두 번 있습니다. 도메인 개체로 한 번, 데이터 전송 개체로 한 번

복제는 비용 이 많이 들기 때문에 아키텍처는 이러한 분리로부터 큰 이점을 얻을 수 있어야합니다.


5
"거대한 비용"에 대해 자세히 설명하십시오. 또한 코드 생성 기술을 사용하여 DTO 클래스를 생성하여 비용을 제거 할 수없는 이유를 설명하십시오.
John Saunders

70
+1. 두번? 운이 좋은 경우에만 :-) DTO로 도메인 엔터티를 복제하는 프로젝트는 보완하기 위해 거의 동일하지만 너무 미묘하게 다른 UI Bean을 갖는 경향이 있습니다. 즉 3이고, 하나님이 금지하는 경우 (웹 서비스 / XML-RPC는 / 무엇이든)이 일어나고, 쉽게 4 또는 5로 얻을 수 리모팅의 일종있다
ChssPly76

17
현재 엔터프라이즈 14 계층 라자냐 아키텍처 (KIDDING 아님)로 작업하고 있습니다. 주로 데이터 전송을위한 11 개 또는 그 이상의 레이어는 무료로 제공되지 않습니다.
KarlP

10
또한 바보 같은 디자인으로 작업 할 때 코드 생성기를 절대적으로 좋아하지만 처음부터 잘못하고있는 것이 확실합니다. b) 그들은 무료로 오지 않는다.
KarlP

7
죄송합니다. 그러나 이는 잘못된 것이며 잘못된 답변이 높은 투표를 받고 수락되었습니다. 우선 리플렉션을 사용하여 DTO를 즉석에서 생성 할 수 있습니다. 둘째, CASE 시스템 또는 oAW에서 "루트 정의"를 사용하여 BO 및 DTO를 생성 할 수 있습니다. 셋째, XSD와 JAXB를 사용하여 DTO를 생성하고 DTO를 BO의 기본으로 사용하거나 XSD에서 두 가지를 모두 생성 할 수 있습니다. 클라이언트 프로그램에 연결 ... 내가 일하는 환경에서, 그의 머리는 곧
금판

128

DTO는 안티 패턴이 아닙니다. 유선으로 데이터를 전송하는 경우 (예 : Ajax 호출의 웹 페이지로) 대상이 사용할 데이터 만 전송하여 대역폭을 절약해야합니다. 또한 프리젠 테이션 계층이 데이터를 기본 비즈니스 오브젝트와 약간 다른 형식으로 갖는 것이 편리한 경우가 종종 있습니다.

나는 이것이 Java 지향 질문이라는 것을 알고 있지만 .NET 언어에서는 익명 유형, 직렬화 및 LINQ를 사용하여 DTO를 즉석에서 구성 할 수 있으므로 DTO를 사용하여 설정 및 오버 헤드를 줄일 수 있습니다.


15
@ 존, 이것은 잘못되었습니다. 나는 항상 그것을한다. 직렬화는 리플렉션을 사용하며 익명 유형에서만 잘 작동합니다. 그냥 객체로 serializer에 전달하십시오. 그리고 일단 직렬화되면 (예를 들어 xml 또는 json으로) 물론 메소드에서 반환 할 수 있습니다.
Gabe Moothart

8
음, 존, 그건 사실이 아니에요 익명 유형을 JSON으로 직렬화 할 수 있습니다. MVC 앱에서 사용해보십시오 : return Json (new {Foo = "Hi there!}); 나는 그것이 잘 작동한다고 약속합니다. 익명 유형은 일반적으로 객체 그래프에서 사이클이 없기 때문에 비 익명 유형보다 더 좋습니다. , 이는 JSON 시리얼 라이저 휴식.
크레이그 Stuntz

1
이러한 의미에서 Json 직렬화는 DTO가 아니므로 적용되지 않습니다. 물론 위의 주장도 적용됩니다. 언젠가는 가치가 없어집니다.
Jim Barrows

1
데이터 중복이없는 경우 Gabe가 맞습니다. DTO는 안티 패턴 그 자체가 아닙니다 (그러나 잘못 사용하는 경우 가능합니다!). 예를 들어 BO는 다른 소스의 데이터를 DTO로 집계 할 수 있습니다.
astro

3
+1. 그리고 대역폭 보존 외에 DTO를 원할 다른 많은 이유가 있습니다. (회사 정책 또는 법률에 따라) 모든 필드를 전송하는 것이 허용됩니까? 또한 우리 회사의 DAO는 이러한 모든 최적화를 수행해야하기 때문에 매우 복잡합니다. 서비스 계층에서 작업하면서 DTO를 사용하게되어 기쁘고 Object X와의 관계에 대해 걱정하지 않아도됩니다. 다른 n 대 n 테이블에.
user64141

25

EJB 3.0의 안티 패턴 DTO는 다음과 같이 말합니다.

EJB 3.0 이전의 EJB 사양에서 Entity Beans의 무거운 특성으로 인해 DTO (Data Transfer Objects)와 같은 디자인 패턴이 사용되었습니다. DTO는 티어를 통해 데이터를 전송하는 데 사용되는 경량 오브젝트 (처음에는 엔티티 Bean이어야 했음)가되었습니다. 이제 EJB 3.0 스펙은 엔티티 Bean 모델을 POJO (Plain old Java Object)와 동일하게 만듭니다. 이 새로운 POJO 모델을 사용하면 더 이상 각 엔티티 또는 엔티티 세트에 대해 DTO를 작성할 필요가 없습니다. 계층 전체에 EJB 3.0 엔티티를 보내려면 java.io.Serialiazable을 구현하십시오.


6
메모리에서 동일한 JVM의 메소드간에 오브젝트를 전송할 때 참입니다. 실제로 와이어를 직렬화하고 직렬화 및 / 또는 지연로드를 유지하는 정도를 제어하려는 경우에는 해당되지 않습니다.
wrschneider

예, 심지어 동일한 JVM에서도 JEE / Spring 트랜잭션 관리를 사용하는 경우 동일한 테마를 유지하도록주의를 기울여야합니다.
Marc

20

DTO는 반 패턴 그 자체가 아니라고 생각하지만 DTO 사용과 관련된 반 패턴이 있습니다. Bill Dudney는 DTO 폭발을 예로 들어 설명합니다.

http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf

여기에 언급 된 여러 DTO 남용이 있습니다.

http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/

계층간에 데이터를 전달하는 수단으로 3 계층 시스템 (일반적으로 EJB를 기술로 사용) 때문에 시작되었습니다. Spring과 같은 프레임 워크를 기반으로하는 대부분의 현대 Java 시스템은 POJO를 단일 계층에서 도메인 오브젝트 (종종 JPA 등으로 주석이 달린 등)를 사용하여 단순화 된 대체보기를 사용합니다. 여기에서 DTO를 사용할 필요는 없습니다.


3
DTO가 적절한 상황에서 사용될 때 반 패턴아닌 좋은 패턴이라는 것이 완전히 옳습니다 . 두 번째 링크는 현재 사용 중지 된 것으로 보이지만 가장 큰 악용은 데이터베이스 상호 작용을위한 모든 "DTO"에 해당하는 "DTO"가있어 아무런 가치도없고 DTO도 아니 었습니다!
David

19

OO 순수 주의자들은 객체가 실제 도메인 객체 대신 데이터 테이블 표현이되기 때문에 DTO가 반 패턴이라고 말한다.


9

일부는 남용 가능성으로 인해 DTO를 반 패턴으로 간주합니다. 필요하지 않거나 필요하지 않을 때 자주 사용됩니다.

이 기사 는 일부 학대를 모호하게 설명합니다.


1
이 기사는 DTO를 남용 할 수있는 패턴으로 훨씬 더 정확하게 설명합니다.
Craig Stuntz

이것은 링크 전용 답변에 해당하며 실제로 기사에서 인용해야합니다. 이것이 답변이 아님으로 표시되지 않은 방법을 모릅니다.
Nathan Hughes

연결이 끊어
Davi Lima

7

분산 시스템을 구축하는 경우 DTO는 반 패턴이 아닙니다. 모든 사람이 그런 의미로 발전하는 것은 아니지만 Open Social 앱 (예를 들어)이 모두 JavaScript로 실행되는 경우입니다.

API에 많은 양의 데이터를 게시합니다. 그런 다음 일부 형태의 객체, 일반적으로 DTO / 요청 객체로 역 직렬화됩니다. 그런 다음 모델 개체로 변환하기 전에 입력 한 데이터가 올바른지 확인하기 위해 유효성을 검사 할 수 있습니다.

제 생각에는 잘못 사용되어 반 패턴으로 간주됩니다. 분산 시스템을 구축하지 않으면 시스템이 필요하지 않을 가능성이 있습니다.


4

데이터 전송 객체 의 목적은 다른 소스의 데이터를 저장 한 다음 데이터베이스 (또는 원격 외관) 로 전송하는 것입니다. 한 번에 ) 입니다.

그러나 DTO 패턴이 단일 책임 원칙을 위반 함 . DTO는 데이터를 저장할뿐만 아니라 데이터를 데이터베이스 / 외부로 전송하기 때문입니다.

데이터베이스 계층분리 해야 할 필요가 있기 때문에 비즈니스 오브젝트와 데이터 오브젝트를 분리 할 필요는 반 패턴이 아닙니다.어쨌든 .

DTO 대신 개체 컬렉션 ( Aggregate )과 데이터 전송 ( Repository ) 을 분리하는 Aggregate and Repository Patterns를 사용해야합니다. ) .

오브젝트 그룹을 전송하려면 저장소 세트와 트랜잭션 컨텍스트를 보유하는 작업 단위 패턴을 사용할 수 있습니다 . 트랜잭션 내에서 집계의 각 오브젝트를 별도로 전송하기 위해.


4

모든 도메인 개체가 연결된 개체를 EAGERly로로드하면 DTO는 필수 요소가되고 안티 패턴이 아닙니다.

DTO를 만들지 않으면 비즈니스 계층에서 클라이언트 / 웹 계층으로 불필요한 개체가 전송됩니다.

이 경우 오버 헤드를 제한하려면 DTO를 전송하십시오.


1

질문은 "why"가 아니라 " when " 이어야합니다 .

확실하게 사용의 결과가 더 높은 비용 일 때 안티 패턴입니다 런타임 또는 유지 관리 입니다. 데이터베이스 엔터티 클래스와 동일한 수백 개의 DTO가있는 프로젝트를 작업했습니다. 단일 필드를 추가하려고 할 때마다 DTO, 엔터티, DTO에서 도메인 클래스 또는 엔터티로의 변환, 역 변환 등의 ID를 4 번 추가하도록 광고합니다. 일관성이 없습니다.

실제로 다른 도메인 클래스 표현이 필요할 때 안티 패턴아닙니다.더 평평하고 더 풍부하고 더 좁은 .

개인적으로 도메인 클래스로 시작하여 올바른 장소에서 적절한 확인을 통해 전달합니다. JSON 또는 XML과 같은 직렬화 형식에 매핑, 데이터베이스, 매핑하기 위해 "도우미"클래스에 주석을 달거나 추가 할 수 있습니다. 필요하다고 생각되면 클래스를 2 개로 항상 분할 할 수 있습니다.

그것은 당신의 관점에 관한 것입니다-도메인 객체를 서로 생성 된 여러 객체 대신 다양한 역할을하는 단일 객체로 보는 것을 선호합니다. 개체의 유일한 역할이 데이터를 전송하는 것이라면 DTO입니다.


1

사람들은 모든 원격 객체를 DTO로 구현하면 반 패턴이 될 수 있다고 생각합니다. DTO는 단지 속성 집합 일 뿐이며 큰 개체가있는 경우 모든 속성을 필요하지 않거나 사용하지 않아도 항상 모든 속성을 전송합니다. 후자의 경우 프록시 패턴 사용을 선호합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.