데이터 전송 객체 란 무엇입니까?


218

데이터 전송 객체 란 무엇입니까?

MVC에는 모델 클래스 DTO가 있으며, 그렇지 않은 경우 차이점은 무엇이며 둘 다 필요합니까?


@ yegor256과 그 기사의 그 책은 API에서 데이터를 검색하는 방법과 DB에 데이터를 저장하는 방법과 SRP를 위반하는 방법을 알고 있습니까?
Betlista

답변:


222

데이터 전송 개체는 데이터를 캡슐화하여 응용 프로그램의 한 하위 시스템에서 다른 하위 시스템으로 보내는 데 사용되는 개체입니다.

DTO는 N 계층 응용 프로그램의 서비스 계층에서 자체적으로 UI 계층간에 데이터를 전송하는 데 가장 일반적으로 사용됩니다. 여기서 주요 이점은 분산 응용 프로그램에서 전선을 통해 전송해야하는 데이터의 양을 줄이는 것입니다. 그들은 또한 MVC 패턴에서 훌륭한 모델을 만듭니다.

DTO의 또 다른 용도는 메소드 호출을위한 매개 변수를 캡슐화하는 것입니다. 방법이 4 개 이상의 매개 변수를 사용하는 경우 유용 할 수 있습니다.

DTO 패턴을 사용할 때는 DTO 어셈블러도 사용합니다. 어셈블러는 도메인 개체에서 DTO를 만드는 데 사용되며 그 반대도 마찬가지입니다.

도메인 개체에서 DTO 로의 변환 및 다시 변환은 비용이 많이 드는 프로세스 일 수 있습니다. 분산 응용 프로그램을 작성하지 않는 경우 Martin Fowler가 설명하는 것처럼 패턴에서 큰 이점을 얻지 못할 수 있습니다.


7
"DTO는 MVC 패턴에서 훌륭한 모델을 만듭니다"-모델에 객체의 모든 데이터가 포함되어 있지 않아야하고 DTO가 데이터의 일부로 최적화되어서는 안됩니까? 모델 A가 있고이를 두 개의 서브 시스템에 전달해야하는 경우 각각의 관련 필드가있는 A_DTO_1 및 A_DTO_2가 있습니까? "DTO는 메소드 호출을위한 매개 변수를 캡슐화 할 수 있습니다"-> 따라서 매개 변수를 랩핑하는 모든 클래스는 분산 시스템이 아니더라도 DTO입니까? MVC의 모델이 도메인 객체가 아닙니까?
Yaron Naveh 2016 년

2
첫 번째 질문에 대한 답으로, 나는 똑같은 것에 대해 이야기하지 않았다고 생각합니다. MVC의 모델이 반드시 도메인 모델의 클래스 일 필요는 없습니다. 그렇게 말하면 잘 될 것입니다. DTO를 사용하면 불필요한 것들이 모두 제거됩니다. 원하는 아키텍처에 따라 다릅니다. 두 번째 질문에 정확히 대답하는 방법을 잘 모르겠습니다. 무선으로 전송하든 아니든간에 (서브) 시스템간에 전송 될 많은 데이터를 캡슐화하는 객체이므로 DTO라고 주장합니다.
베니 할렛

12
"DTO의 또 다른 용도는 메소드 호출에 대한 매개 변수를 캡슐화하는 것입니다. 이는 메소드가 4 개 또는 5 개 이상의 매개 변수를 사용하는 경우 유용 할 수 있습니다." 이것은 실제로 Poltergeist 또는 Gypsy Wagon 클래스라고 불리는 반 패턴입니다. 메소드에 4 개의 인수가 필요한 경우 4를 지정하십시오. 오브젝트를 메소드 또는 클래스로 이동시키기 위해 클래스를 작성하지 마십시오.
Wix

2
@Wix, 좋은 지적. 그러나 의미 론적으로 올바른 경우 (예 : 속성 자체가 아닌 속성이있는 설정 클래스를 값으로 전달하는 경우) 이것이 괜찮다고 주장합니다. 하지 말아야 할 것은 하나의 객체를 전달하기 위해 모든 논쟁을 던지는 것입니다. 왜냐하면 그것들은 관련이 없으며 나중에 악몽이 풀릴 수 있기 때문입니다.
Aram Kocharyan

3
DTO를 사용하여 메서드 호출 (LocalDTO로 만들 것)에 대한 매개 변수를 캡슐화하지 않아야합니다. 원격 인터페이스의 컨텍스트에서 소개되었습니다. martinfowler.com/bliki/LocalDTO.html
Rui

28

DTO에 대한 정의는 Martin Fowler 's site 에서 찾을 수 있습니다 . DTO는 매개 변수를 메소드 및 리턴 유형으로 전송하는 데 사용됩니다. 많은 사람들이 UI에서 이들을 사용하지만 다른 사람들은 도메인 객체를 팽창시킵니다.


22

DTO는 멍청한 객체입니다. 단지 속성을 보유하고 있으며 게터와 세터를 가지고 있지만, 비교 () 또는 equals () 구현 이외의 다른 의미의 논리는 없습니다.

일반적으로 MVC의 모델 클래스 (여기서는 .net MVC라고 가정)는 DTO 또는 DTO 모음 / 집합입니다.


3
당신이 설명하는 것은 LocalDTO입니다 : martinfowler.com/bliki/LocalDTO.html
Rui

3
DTO와 같은 것을 사용하는 것이 유용한 경우는 프레젠테이션 계층의 모델과 기본 도메인 모델이 크게 일치하지 않는 경우입니다. 이 경우 도메인 모델에서 매핑하고 프리젠 테이션에 편리한 인터페이스를 제공하는 프리젠 테이션 특정 파사드 / 게이트웨이를 만드는 것이 좋습니다.
Amitābha

14

일반적으로 Value Objects 는 변경할 수 없어야합니다. Java의 Integer 또는 String 객체 와 유사합니다 . 소프트웨어 계층간에 데이터를 전송하는 데 사용할 수 있습니다. 소프트웨어 계층 또는 서비스가 마이크로 서비스 환경 또는 레거시 Java Enterprise 앱과 같은 다른 원격 노드에서 실행되는 경우 우리는 두 클래스의 거의 정확한 사본을 만들어야합니다. 이것이 우리가 DTO를 만난 곳입니다.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

레거시 Java Enterprise Systems에서 DTO는 다양한 EJB 항목을 포함 할 수 있습니다.

이것이 모범 사례인지는 모르지만 개인적으로 다음과 같이 Spring MVC / Boot Project에서 Value Objects 를 사용 합니다.

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

컨트롤러 계층은 엔티티가 무엇인지 모릅니다. FormView Value Objects 와 통신 합니다. Form Objects에는 JSR 303 Validation 주석 (예 : @NotNull)이 있으며 View Value Objects 에는 사용자 지정 직렬화를위한 Jackson Annotations가 있습니다. (예 : @JsonIgnore)

서비스 계층은 엔티티 개체를 사용하여 저장소 계층과 통신합니다. 엔터티 객체에는 JPA / Hibernate / Spring Data 주석이 있습니다. 모든 계층은 하위 계층과 만 통신합니다. 순환 / 순환 종속성으로 인해 계층 간 통신이 금지됩니다.

User Service ----> XX CANNOT CALL XX ----> Order Service

일부 ORM 프레임 워크는 추가 인터페이스 또는 클래스를 사용하여 프로젝션 할 수 있습니다. 따라서 리포지토리는 View 개체를 직접 반환 할 수 있습니다. 추가 변환이 필요하지 않습니다.

예를 들어 이것은 User 개체입니다.

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

그러나 ID, 이름, 성만 포함하는 페이지 매김 사용자 목록을 반환해야합니다. 그런 다음 ORM 투영을위한 View Value Object를 작성할 수 있습니다.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

저장소 계층에서 페이지 매김 결과를 쉽게 얻을 수 있습니다. 스프링 덕분에 투영을위한 인터페이스 만 사용할 수도 있습니다.

List<UserListItemView> find(Pageable pageable);

다른 변환 작업 BeanUtils.copy방법이 잘 작동하는지 걱정하지 마십시오 .


11
  1. DTO무엇인지 에 대한 가장 좋은 대답 은 DTO테스트가 필요한 비즈니스 로직이나 메소드 구현을 포함해서는 안되는 간단한 객체라는 것 입니다.
  2. 일반적으로 MVC 패턴을 사용하는 모델은 지능형 모델이며 해당 모델에 대해 다른 작업을 수행하는 많은 / 일부 메소드를 포함 할 수 있습니다 (비즈니스 로직이 아니라 컨트롤러에 있어야 함). 그러나 데이터를 전송할 때 (예 : 어딘가에서 REST ( GET/ POST/ whatever) 엔드 포인트 호출 또는 SOA를 사용하여 웹 서비스 사용 등) 필요하지 않은 코드로 큰 크기의 객체를 전송하고 싶지 않습니다. 엔드 포인트는 데이터를 소비하고 전송 속도를 느리게합니다.

비즈니스 로직이 컨트롤러에 있어야하는 이유는 무엇입니까?
AlexioVay

6

MVC에서 데이터 전송 객체는 종종 도메인 모델을 더 간단한 객체에 매핑하여 최종적으로 뷰에 표시됩니다.

에서 위키 백과 :

이전에는 값 개체 또는 VO라고 알려진 DTO (데이터 전송 개체)는 소프트웨어 응용 프로그램 하위 시스템간에 데이터를 전송하는 데 사용되는 디자인 패턴입니다. DTO는 종종 데이터베이스에서 데이터를 검색하기 위해 데이터 액세스 개체와 함께 사용됩니다.


3
값 개체는 DTO 가 아닙니다 .
coderpc

0

데이터 전송 개체 (DTO)는 "프로세스간에 데이터를 전달하는 개체"(Wikipedia) 또는 "데이터를 캡슐화하여 응용 프로그램의 한 하위 시스템에서 다른 하위 시스템으로 전송하는 개체"(스택 오버플로 응답)를 설명합니다.


0

정의

DTO는 하드 코드 된 데이터 모델입니다. 모든 필드가 컴파일 타임에 알려지고 강력한 유형의 속성을 통해 액세스 되는 하드 코딩 된 생산 프로세스에서 처리하는 데이터 레코드를 모델링하는 문제 만 해결합니다 .

반대로, 동적 모델 또는 "속성 백"은 생산 프로세스가 런타임에 생성 될 때 데이터 레코드 모델링 문제를 해결합니다.

크바

DTO는 필드 또는 속성으로 모델링 할 수 있지만 누군가 Cvar이라는 매우 유용한 데이터 컨테이너를 발명했습니다. 값에 대한 참조입니다. DTO가 내가 참조 속성 이라고 부르는 모델로 모델링 할 때 힙 메모리를 공유하도록 모듈을 구성하여 공동으로 작업 할 수 있습니다. 이를 통해 코드에서 매개 변수 전달 및 O2O 통신이 완전히 제거됩니다. 다시 말해, 기준 속성을 갖는 DTO는 코드가 제로 커플 링을 달성 할 수있게한다 .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

출처 : http://www.powersemantics.com/

동적 DTO는 동적 소프트웨어에 필요한 구성 요소입니다. 동적 프로세스를 인스턴스화하기 위해 한 가지 컴파일러 단계는 스크립트의 각 시스템을 스크립트가 정의한 참조 특성에 바인드하는 것입니다. 컬렉션에 Cvar을 추가하여 동적 DTO를 빌드합니다.

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

경합

참고 : Wix는 매개 변수를 "반 패턴 (anti-pattern)"으로 구성하기 위해 DTO 사용을 표시 했으므로 권위있는 의견을 제시 할 것입니다.

    return View(model);  // MVC disagrees

저의 협업 아키텍처는 디자인 패턴을 대체합니다. 내 웹 기사를 참조하십시오.

매개 변수는 스택 프레임 기계를 즉시 제어합니다. 연속 제어를 사용하므로 즉각적인 제어가 필요하지 않은 경우 모듈에 매개 변수가 필요하지 않습니다. 내 건축에는 없습니다. 기계 (방법)의 공정 중 구성은 매개 변수가 값 유형일 때 복잡성과 값 (성능)을 추가합니다. 그러나 참조 유형 매개 변수는 소비자가 캐시 누락으로 인해 힙에서 값을 가져 오는 원인이되므로 소비자를 참조 특성으로 구성하십시오. 기계 공학의 사실 : 매개 변수에 대한 의존은 가공 (구성 요소 제작) 자체가 낭비이기 때문에 일종의 사전 최적화입니다. 자세한 내용은 내 W 기사를 참조하십시오. http://www.powersemantics.com/w.html .

Fowler와 회사는 다른 아키텍처를 알고 있다면 분산 아키텍처 외부의 DTO의 이점을 인식 할 수 있습니다. 프로그래머는 분산 시스템 만 알고 있습니다. 통합 협업 시스템 (일명 생산 aka 제조)은 필자가 이런 방식으로 코드를 작성하는 최초의 사람이기 때문에 자체 아키텍처라고 주장해야합니다.

일부는 DTO를 빈혈 도메인 모델로 간주합니다. 즉, 기능이 부족하지만 이는 객체가 상호 작용하는 데이터를 소유해야한다고 가정합니다. 그런 다음이 개념 모델을 사용하면 분산 처리를위한 모델 인 개체간에 데이터를 전달할 수 있습니다. 그러나 제조 라인에서 각 단계는 최종 제품에 액세스하여 소유 또는 제어하지 않고 최종 제품을 변경할 수 있습니다. 이것이 분산 처리와 통합 처리의 차이입니다. 제조는 제품을 운영 및 물류와 분리합니다.

물류 및 반품 문제를 처리 할 때 발생하는 모든 추가 작업과 두통을 제외하고는 전자 메일 추적을 유지하지 않고 서로 전자 메일로 작업을 수행하는 쓸모없는 회사 직원으로서 모델링 처리에는 본질적으로 잘못된 것이 없습니다. 적절하게 모델링 된 분산 프로세스는 문서에 어떤 문서가 왔고 어떤 작업을할지 설명하는 문서 (액티브 라우팅)를 첨부합니다. 활성 라우팅은 프로세스 소스 라우팅의 복사본으로, 프로세스가 시작되기 전에 작성됩니다. 결함 또는 기타 비상 변경이 발생하면 활성 라우팅은 전송 될 조작 단계를 포함하도록 수정됩니다. 이것은 생산에 투입된 모든 노동을 설명합니다.

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