일반 이전 CLR 개체 대 데이터 전송 개체
POCO = Plain Old CLR(또는 그 이상:클래스) 객체
DTO = 데이터 전송 개체
이 게시물에는 차이가 있지만 솔직히 제가 읽은 대부분의 블로그는 DTO가 정의된 방식으로 POCO를 설명합니다. DTO는 애플리케이션 계층 간에 데이터를 이동하는 데 사용되는 단순한 데이터 컨테이너입니다.
POCO와 DTO는 같은 것입니까?
POCO는 OOP의 규칙을 따릅니다.국가와 행동을 가져야 합니다(하지만 그럴 필요는 없습니다).POCO는 마틴 파울러(Martin Fowler)가 만든 POCO에서 유래했습니다.그는 POJO라는 용어를 프레임워크의 무거운 EJB 구현을 거부하는 것을 보다 섹시하게 만드는 방법으로 사용했습니다.POCO는 에서 동일한 컨텍스트에서 사용해야 합니다.넷. 프레임워크가 객체의 설계를 지시하지 않도록 합니다.
DTO의 유일한 목적은 상태를 전송하는 것이며 동작이 없어야 합니다.이 패턴의 사용 예는 DTO에 대한 Martin Fowler의 설명을 참조하십시오.
여기 차이점이 있습니다. POCO는 프로그래밍(좋은 구식 객체 지향 프로그래밍)에 대한 접근 방식을 설명합니다. 여기서 DTO는 객체를 사용하여 "데이터를 전송"하는 데 사용되는 패턴입니다.
POCO를 DTO처럼 처리할 수는 있지만, 그렇게 할 경우 빈혈 도메인 모델을 생성할 위험이 있습니다.또한 DTO는 비즈니스 도메인의 실제 구조를 나타내는 것이 아니라 데이터를 전송하도록 설계되어야 하기 때문에 구조적으로 불일치가 있습니다.그 결과 DTO는 실제 도메인보다 더 평평한 경향이 있습니다.
합리적인 복잡성을 가진 도메인에서는 거의 항상 별도의 도메인 POCO를 생성하여 DTO로 변환하는 것이 좋습니다. DDD(도메인 기반 설계)는 부패 방지 계층(여기서는 또 다른 링크이지만 가장 좋은 방법은 책을 사는 것)을 정의합니다. 이는 분리를 명확하게 하는 좋은 구조입니다.
이미 블로그 기사에 제 입장을 밝혔기 때문에 제가 기여하는 것은 중복될 수 있지만, 그 기사의 마지막 단락은 다음과 같은 내용을 요약합니다.
그래서 결론적으로, POCO를 사랑하는 법을 배우고, 그것이 DTO와 같은 것이라는 잘못된 정보를 퍼뜨리지 않도록 해야 합니다.DTO는 애플리케이션 계층 간에 데이터를 이동하는 데 사용되는 단순한 데이터 컨테이너입니다.POCO는 지속성 무식(get 또는 save 메소드 없음)이라는 한 가지 요구 사항을 가진 완전한 비즈니스 개체입니다.마지막으로, 만약 여러분이 아직 지미 닐슨의 책을 빌리지 않았다면, 여러분의 지역 대학에서 그것을 찾으세요.이것은 C#에 예시가 있고 훌륭한 읽을거리입니다.
그나저나 패트릭 저는 POCO를 라이프스타일 기사로 읽었고, 저는 전적으로 동의합니다, 그것은 환상적인 기사입니다.이것은 제가 추천한 지미 닐슨 책의 한 부분입니다.저는 그것이 온라인으로 가능한지 전혀 몰랐습니다.그의 책은 POCO / DTO / Repository / 및 기타 DDD 개발 관행에 대한 최고의 정보 출처입니다.
POCO는 단순히 외부 프레임워크에 의존하지 않는 객체입니다.평범합니다.
POCO의 행동 여부는 중요하지 않습니다.
DTO는 도메인 개체(일반적으로 행동이 풍부한)와 마찬가지로 POCO일 수 있습니다.
일반적으로 DTO는 일반적으로 시스템 경계에서 빠져나가기 때문에 직렬화 목적으로 외부 프레임워크(예: 속성)에 의존할 가능성이 더 높습니다.
일반적인 Onion 스타일 아키텍처(광범위한 DDD 접근 방식 내에서 자주 사용됨)에서는 도메인 계층이 중앙에 배치되므로 이 시점에서 해당 계층의 개체가 해당 계층 외부에 종속성을 갖지 않아야 합니다.
저는 그 주제에 대한 기사를 썼습니다: DTO vs Value Object vs POCO.
간단히 말해서:
- DTO!= 값 개체
- DTO ⊂ POCO
- 값 객체 » POCO
저는 DTO가 POCO가 될 수 있다고 생각합니다. DTO는 객체의 사용에 관한 것이고 POCO는 객체의 스타일에 관한 것입니다(건축 개념에서 분리됨).
POCO가 DTO와 다른 한 가지 예로 도메인 모델/비즈니스 논리 모델 내의 POCO를 들 수 있습니다. 이는 문제 도메인을 OO로 표현한 것입니다.전체 응용 프로그램에서 POCO를 사용할 수 있지만, 이 경우 지식 유출과 같은 바람직하지 않은 부작용이 발생할 수 있습니다.예를 들어 DTO는 UI가 통신하는 서비스 계층에서 사용되며, DTO는 데이터의 플랫 표현이며 UI에 데이터를 제공하고 변경 사항을 서비스 계층에 전달하는 데만 사용됩니다.서비스 계층은 DTO의 양방향을 POCO 도메인 개체에 매핑하는 작업을 담당합니다.
업데이트 Martin Fowler는 이 접근 방식은 어려운 문제이며 도메인 계층과 사용자 인터페이스 간에 상당한 불일치가 있는 경우에만 수행해야 한다고 말했습니다.
TL;DR:
DTO는 상태 전송 패턴을 설명합니다.POCO는 특별한 것이 없다는 것을 제외하고는 많은 것을 설명하지 않습니다.이것은 OOP에서 "객체"라고 말하는 또 다른 방법입니다.그것은 마틴 파울러에 의해 만들어진 POJO(Java)에서 유래했는데, 그는 문자 그대로 '객체'를 위한 더 화려한 이름으로 묘사했습니다. 왜냐하면 '객체'는 별로 섹시하지 않고 사람들이 그렇게 피했기 때문입니다.
확장 중...
좋아요. DTO에 대한 원래 질문부터 시작하여 제가 생각했던 것보다 훨씬 더 고급스러운 방식으로 설명해 드리겠습니다.
DTO는 관심 계층 간에 상태를 전송하는 데 사용되는 개체 패턴입니다.그들은 그 행동이 상태를 변화시키지 않는 한 행동(기술적으로 포코일 수 있음)을 가질 수 있습니다.예를 들어, 자신을 직렬화하는 방법이 있을 수 있습니다.적절한 DTO가 되려면 단순한 속성 가방이어야 합니다. 이 개체는 강력한 모델이 아니며 의미론적 의미가 없으며 비즈니스 규칙이나 불변성을 강제하지 않는다는 점을 분명히 해야 합니다.말 그대로 데이터를 이동하기 위해서만 존재합니다.
POCO는 일반적인 개체이지만 '일반'이라는 의미는 특별하지 않고 특정 요구사항이나 규정이 없다는 것입니다.이는 CLR 객체에 암시적인 패턴이 없다는 것을 의미합니다.일반적인 용어.저는 또한 그것이 다른 프레임워크와 함께 작동하도록 만들어지지 않았다는 사실을 설명하기 위해 확장되었다는 것을 들었습니다.예를 들어, POCO에 EF 장식이 여러 개 있는 경우, 단순한 POCO가 아니며 DAO의 영역에 더 가깝다고 생각합니다. DAO는 DTO와 추가 데이터베이스 문제(예: 매핑 등)를 결합한 것입니다.POCO는 학교에서 만드는 것을 배우는 물체처럼 자유롭고 방해받지 않습니다.
다음은 비교할 다양한 종류의 객체 패턴의 몇 가지 예입니다.
- 뷰 모델: 뷰의 데이터를 모델링하는 데 사용됩니다.일반적으로 특정 뷰(일반적으로 공유 객체가 아님) 또는 오늘날의 특정 뷰 구성요소(예: React)에 대한 바인딩 및 검증을 지원하는 데이터 주석이 있습니다.MVVM에서는 컨트롤러 역할도 합니다.이것은 DTO 이상의 것입니다. 상태를 전송하는 것이 아니라 상태를 표시하는 것입니다. 더 구체적으로는 UI에 유용한 방식으로 상태를 형성하는 것입니다.
- Value Object: 값을 나타내는 데 사용되며 불변해야 합니다.
- 집계 루트: 상태 및 불변량을 관리하는 데 사용됩니다.ID 이외의 내부 엔티티에 대한 참조를 허용하면 안 됩니다.
- 처리기: 이벤트/메시지에 응답하는 데 사용됩니다.
- 속성: 횡단 관심사를 처리하기 위한 장식으로 사용됩니다.특정 개체 수준(예: 속성은 클래스가 아닌 것, 메서드는 속성이 아닌 것 등)에서만 사용할 수 있습니다.
- 서비스: 복잡한 작업을 수행하는 데 사용됩니다.전형적으로 어떤 형태의 외관.
- 컨트롤러: 요청 및 응답 흐름을 제어하는 데 사용됩니다.일반적으로 특정 프로토콜에 제한되거나 일종의 중재자 역할을 합니다. 특정 책임이 있습니다.
- 공장: 생성자가 충분하지 않을 때 사용할 복잡한 객체를 구성 및/또는 조립하는 데 사용됩니다.또한 런타임에 어떤 개체를 만들어야 하는지 결정하는 데 사용됩니다.
- 리포지토리/DAO: 데이터에 액세스하는 데 사용됩니다.일반적으로 CRUD 작업을 노출하거나 데이터베이스 스키마를 나타내는 개체로, 구현 관련 속성으로 표시할 수 있습니다.사실, 이 스키마 DAO 객체 중 하나는 사실 다른 종류의 DTO입니다.
- API 계약: 직렬화 속성으로 표시될 가능성이 높습니다.일반적으로 공개 게터와 세터가 필요하며 너무 복잡한 그래프가 아닌 경량이어야 합니다. 직렬화와 관련되지 않은 방법은 일반적이지 않고 권장되지 않습니다.
이들은 단순한 개체로 볼 수 있지만 대부분은 일반적으로 패턴에 묶여 있거나 암묵적인 제한이 있습니다.그래서 여러분은 그것들을 "객체"라고 부를 수도 있고, 그것의 의도에 대해 더 구체적으로 말할 수도 있고, 그것이 무엇인지에 따라 부를 수도 있습니다.이것이 우리가 디자인 패턴을 가지고 있는 이유이기도 합니다. 복잡한 개념을 몇 마디로 설명하자면 말이죠.DTO는 패턴입니다.Aggregate 루트는 패턴이고 View Model은 패턴입니다(예: MVC 및 MVVM).
POCO는 패턴을 설명하지 않습니다.이것은 OOP의 클래스/객체를 지칭하는 다른 방식일 뿐이며 무엇이든 될 수 있습니다.추상적인 개념이라고 생각해보세요. 그들은 무엇이든 언급할 수 있습니다.IMO, 단방향 관계가 있습니다. 왜냐하면 한 물체가 한 가지 목적만을 깨끗하게 수행할 수 있는 지점에 도달하면, 그것은 더 이상 POCO가 아니기 때문입니다.예를 들어, 클래스를 어떤 프레임워크(즉, '계기')와 함께 작동하도록 장식으로 표시하면 더 이상 POCO가 아닙니다.따라서 다음과 같은 논리적 관계가 있다고 생각합니다.
- DTO는 계측될 때까지 POCO입니다.
- POCO가 DTO가 아닐 수 있음
- View 모델은 POCO입니다(계측될 때까지).
- POCO가 View Model이 아닐 수 있음
두 가지를 구별하는 것은 패턴을 명확하고 일관되게 유지하여 문제를 해결하고 긴밀한 결합으로 이어지지 않도록 하는 것입니다.예를 들어 상태를 변환하는 메서드가 있지만 API 끝점을 통해 다시 전송할 수 있도록 SQL Server 및 Json Property에 저장하기 위한 EF 장식으로 장식된 비즈니스 개체가 있는 경우입니다.이 개체는 변경할 수 없으며 속성의 변형(예: UserId, UserPk, UserKey, UserGuid)으로 흩어져 있을 수 있습니다. 여기서 일부는 DB에 저장되지 않도록 표시되고 다른 일부는 API 끝점에서 JSON에 직렬화되지 않도록 표시됩니다.
그래서 만약 당신이 제게 DTO가 무엇인지 말한다면, 저는 그것이 움직이는 상태 외에는 다른 어떤 것에도 사용되지 않았다는 것을 확실히 할 것입니다.만약 당신이 나에게 뷰 모델이 있다고 말한다면, 나는 그것이 데이터베이스에 저장되지 않았는지 확인할 것이고, 나는 UI가 데이터를 사용할 수 있도록 '해킹'한 것들을 거기에 넣어도 괜찮다는 것을 알 것입니다.도메인 모델이 무엇인지 말씀해 주신다면, 도메인 외부에 의존하지 않고 기술 구현 세부 사항(데이터베이스, 서비스 등)에 의존하지 않고 추상화만 적용할 수 있습니다.하지만 만약 당신이 저에게 무언가가 POCO라고 말했다면, 당신은 그것이 아닌 것과 마찬가지로 저에게 많은 것을 알려주지 않을 것이고, 도구화되어서는 안 됩니다.
예
이는 약하지만 정확한 예이며 쉽게 따를 수 있어야 합니다.
이것은 POCO일 수도 있고 DTO일 수도 있습니다.그것은 단지 물체일 뿐 특별한 것은 아닙니다.약한 타입의 부동산 가방처럼 보이지만, 눈에 띄는 것은 없습니다.
public class CreateUserRequest
{
public string Name { get; set; }
public string Email { get; set; }
}
더 이상 POCO가 아닙니다.
public class CreateUserRequest
{
[JsonPropertyName(Name = "name")]
public string Name { get; set; }
[JsonPropertyName(Name = "email")]
public string Email { get; set; }
}
왜 POCO가 더 이상 없는 거지?왜냐하면 이것은 분명히 시스템과 함께 작동하도록 고안된 데이터 계약이기 때문입니다.Text.Json 시리얼라이저.이제는 DTO에 가깝지만 특정 프레임워크에 적합합니다.
다음은 여러분이 이러한 구별을 하지 않을 때 일어나는 일입니다.
[Table("Users")]
public class CreateUserRequest
{
[Key]
[JsonIgnore]
public string Id { get; set; }
[JsonPropertyName(Name = "name")]
public string Name { get; set; }
[JsonPropertyName(Name = "email")]
public string Email { get; set; }
public int LoginCount { get; set; }
public void IncrementLogin() => LoginCount++;
}
이제 이것은 확실히 더 이상 POCO가 아닙니다.일종의 DTO인 것처럼 보이지만, 목적이 과중합니다.API 계약인가요, DAO인가요?그것은 JSON 계약과 데이터베이스 ORM 둘 다로 작동하기 위해 만들어진 것으로 보입니다.REST API에서 데이터베이스 PK가 유출되는 것을 방지하기 위해서만 추가 계측이 필요합니다.또한 상태를 도메인 엔티티로 사용하는 것처럼 변환하는 방법도 있습니다.개발자가 의도했는지조차 명확하지 않습니다.LoginCount
JSON 계약 또는 데이터베이스 스키마의 일부입니다.
이 수업은 수업을 재사용함으로써 시간을 절약하고 있다고 생각하는 개발자들에게서 많이 볼 수 있습니다.그들은 이것이 드라이라고 생각합니다.저는 여러분이 그것이 드라이라고 주장할 수 있다고 생각합니다. 하지만 실제로, 그것은 고안되고, 긴밀하게 연결되어 있고, 아마도 5개의 다른 디자인 철학을 위반하고, 결국 미래에 여러분을 망치게 될 것입니다.
역사
파울러의 설명을 인용하자면:사물이 화려했던 세상(예: 특정 패턴을 따르거나 기구가 있는 등)에서, 어떻게든 사람들이 비즈니스 논리를 포착하기 위해 화려하지 않은 사물을 사용하는 것을 피하도록 장려했습니다.그래서 그들은 그것에 PoJO라는 멋진 이름을 붙였습니다.예를 들어, 그가 언급한 것은 "엔티티 빈"입니다. 이것은 매우 구체적인 관례와 요구사항 등을 가진 그런 종류의 물체 중 하나입니다.만약 당신이 그것이 무엇인지 모른다면 --> 자바빈즈.
반대로 POJO/POCO는 학교에서 만드는 것을 배우는 일반적인 역할 객체입니다.
DTO의 주요 사용 사례는 웹 서비스에서 데이터를 반환하는 것입니다.이 경우 POCO와 DTO는 동일합니다.POCO의 모든 동작은 웹 서비스에서 반환될 때 제거되므로 동작 여부는 중요하지 않습니다.
DTO 개체는 데이터를 다른 소스의 개체로 역직렬화하는 데 사용됩니다.이러한 개체는 POCO(모델) 개체가 아닙니다.이러한 개체를 모델(POCO) 개체로 변환해야 합니다.변환은 대부분 복사 작업입니다.내부 소스인 경우 소스에서 직접 이러한 POCO 개체를 채울 수 있지만 외부 소스인 경우에는 권장되지 않습니다.외부 소스에는 사용하는 스키마에 대한 설명이 포함된 API가 있습니다.그러면 DTO에 요청 데이터를 로드하고 POCO의 데이터를 변환하는 것이 훨씬 쉬워집니다.네, 추가 단계이지만 이유가 있습니다.규칙은 소스의 데이터를 개체에 로드하는 것입니다.JSON, XML 등이 될 수 있습니다.로드되면 해당 데이터를 모델에 필요한 것으로 변환합니다.그래서 대부분의 경우 DTO는 외부 소스의 객체 이미지입니다.때로는 소스 공급자의 스키마를 사용하여 훨씬 쉽게 역직렬화할 수도 있습니다. XML은 XSD와 마찬가지로 작동합니다.
일반적인 규칙은 다음과 같습니다. DTO== 명령 및 오버엔지니어링된 소프트웨어의 표시기.POCO==좋습니다.'엔터프라이즈' 패턴은 자바 EE 세계의 많은 사람들의 뇌를 파괴했습니다. 의 실수를 반복하지 마십시오.NET 랜드.
DTO라고 부르지도 마그들은 모델이라고 불립니다.주기. 모델들은 절대 행동하지 않습니다.누가 이런 멍청한 DTO라는 용어를 생각해냈는지는 모르겠지만 분명 a일 것입니다.NET은 제가 이해할 수 있는 전부입니다.MVC의 뷰 모델을 생각해 보세요. 동일한 댐**과 같은 것으로, 모델은 레이어 서버 측 또는 와이어 기간 동안 상태를 전송하는 데 사용되며, 모두 모델입니다.데이터가 있는 속성입니다.이것들은 여러분이 전선을 통과하는 모델들입니다.모델, 모델 모델.바로 그겁니다.
나는 DTO라는 어리석은 용어가 우리의 어휘에서 사라졌으면 좋겠습니다.
언급URL : https://stackoverflow.com/questions/725348/plain-old-clr-object-vs-data-transfer-object
'programing' 카테고리의 다른 글
정렬 목록과 정렬된 사전의 차이점은 무엇입니까? (0) | 2023.05.01 |
---|---|
HttpContent 사용 방법을 찾을 수 없습니다. (0) | 2023.05.01 |
GIT 리포지토리를 한 서버에서 새 서버로 마이그레이션하는 방법 (0) | 2023.05.01 |
datetime 매개 변수를 전달하는 방법은 무엇입니까? (0) | 2023.05.01 |
재정의에 대한 모범 사례는 동일: 및 해시입니다. (0) | 2023.05.01 |