programing

DTO를 도메인 개체에 매핑하기 위한 모범 사례?

starjava 2023. 6. 1. 21:38
반응형

DTO를 도메인 개체에 매핑하기 위한 모범 사례?

DTO를 도메인 개체에 매핑하는 것과 관련된 질문을 많이 보았지만, 그들이 제 질문에 답을 해준다고는 생각하지 못했습니다.저는 이전에 많은 방법을 사용했고 저만의 의견이 있지만 조금 더 구체적인 것을 찾고 있습니다.

상황:

도메인 개체가 많습니다.CSLA 모델을 사용하여 도메인 개체가 매우 복잡할 수 있으며 자체 데이터 액세스가 포함되어 있습니다.당신은 이것들을 전선에 돌리고 싶지 않을 것입니다.데이터를 다양한 형식(.)으로 반환하는 새로운 서비스를 작성할 예정입니다.넷, JSON 등).이러한 이유(및 기타 이유)로 인해 유선상으로 전달할 희박한 데이터 전송 개체도 만들고 있습니다.

제 질문은:DTO와 도메인 개체를 연결하는 방법을 선택합니다.

저의 첫 번째 반응은 파울러, DTO 패턴형 솔루션을 사용하는 것입니다.저는 이것이 하는 것을 여러 번 보았고 그것은 제게 맞는 것처럼 느껴집니다.도메인 개체에 DTO에 대한 참조가 없습니다.도메인 개체에서 DTO를 생성하기 위해 외부 엔티티("매퍼" 또는 "어셈블러")를 호출합니다.일반적으로 도메인 개체 측에는 ORM이 있습니다.이러한 단점은 "매퍼"가 실제 상황에서 매우 복잡해지는 경향이 있으며 매우 취약할 수 있다는 것입니다.

또 다른 아이디어는 도메인 개체가 DTO를 "포함"하는 것입니다. DTO는 단순한 데이터 개체이기 때문입니다.도메인 개체 속성은 내부적으로 DTO 속성을 참조하며, 요청이 있을 경우 DTO를 반환할 수 있습니다.저는 이것에 대해 아무런 문제가 없다고 생각하지만, 그것은 잘못된 느낌입니다.NHibernate를 사용하는 사람들이 이 방법을 사용하는 것으로 보이는 기사를 본 적이 있습니다.

다른 방법이 있습니까?위의 방법 중 하나를 사용할 가치가 있습니까?만약 그렇다면, 그렇지 않다면, 왜?

도메인과 DTO 사이에 매퍼를 두는 것의 이점은 단일 매핑만 지원할 때는 나타나지 않지만 매핑 수가 증가함에 따라 해당 코드를 도메인에서 분리하면 도메인을 더 단순하고 간소하게 유지할 수 있습니다.당신은 많은 추가적인 비중으로 당신의 영역을 혼란스럽게 하지 않을 것입니다.

개인적으로, 저는 제 도메인 엔티티에서 매핑을 유지하고 "매니저/서비스 계층"이라고 부르는 것에 책임을 둡니다.이 계층은 애플리케이션과 리포지토리 사이에 위치하며 워크플로우 조정과 같은 비즈니스 로직을 제공합니다(A를 수정하는 경우 A 서비스가 B 서비스와 함께 작동하도록 B도 수정해야 할 수 있습니다).

가능한 종료 형식이 많다면, 예를 들어 방문자 패턴을 사용하여 엔티티를 변환할 수 있는 플러그형 포맷터를 만들 수도 있지만, 아직 이렇게 복잡한 것에 대한 필요성을 찾지 못했습니다.

Jimmy Bogard가 작성한 것과 같은 자동 장치를 사용할 수 있습니다. 이러한 자동 장치는 개체 간에 연결되지 않고 명명 규칙을 준수해야 합니다.

매핑 로직을 엔티티 내부에 유지한다는 것은 도메인 개체가 이제 알 필요가 없는 "구현 세부사항"을 인식한다는 것을 의미합니다.일반적으로 DTO는 (수신 요청에서 또는 외부 서비스/데이터베이스에서 읽기를 통해) 외부로 향하는 게이트웨이입니다.엔티티는 비즈니스 로직의 일부이므로 이러한 세부 정보는 엔티티 외부에 보관하는 것이 가장 좋습니다.

지도를 다른 곳에 보관하는 것이 유일한 대안이 될 것입니다. 하지만 어디로 가야 할까요?저는 매핑 객체/서비스를 소개하려고 했지만 결국 너무 엔지니어링적인 것처럼 보였습니다.저는 오토매퍼 등을 소규모 프로젝트에 사용하는 데 성공했지만 오토매퍼와 같은 툴에는 자체적인 함정이 있습니다.오토매퍼의 매핑은 암묵적이고 코드의 나머지 부분과 완전히 분리되어 있기 때문에 매핑과 관련하여 찾기 어려운 문제가 몇 가지 있었습니다("관심 분리"가 아니라 "신이 잊혀진 매핑이 어디에 있는지"에 더 가깝기 때문입니다).오토매퍼가 그 용도를 가지고 있지 않다는 것은 아닙니다. 왜냐하면 그것은 사용하기 때문입니다.저는 지도 제작이 문제를 피하기 위해 가능한 한 명확하고 투명한 것이어야 한다고 생각합니다.

매핑 서비스 계층을 생성하는 대신 DTO 내부에서 매핑을 유지하는 데 많은 성공을 거두었습니다.DTO는 항상 응용프로그램의 경계에 위치하므로 비즈니스 개체를 인식하고 해당 개체와의 매핑 방법을 파악할 수 있습니다.매핑 수가 많은 양으로 확장되는 경우에도 깔끔하게 작동합니다.모든 매핑이 한 곳에 있으므로 데이터 계층, 손상 방지 계층 또는 프레젠테이션 계층 내에서 여러 매핑 서비스를 관리할 필요가 없습니다.대신, 매핑은 요청/응답과 관련된 DTO에 위임된 구현 세부 정보일 뿐입니다.일반적으로 직렬화 프로그램은 유선으로 전송할 때 속성과 필드만 직렬화하므로 문제가 발생하지 않아야 합니다.개인적으로, 저는 이것이 가장 깨끗한 옵션이라는 것을 발견했고, 제 경험에 따르면, 이것은 큰 코드 기반에서 잘 확장된다고 말할 수 있습니다.

매핑 양이 불합리한 양으로 확장되는 경우(10년 이상 동안 아직 발생하지 않은 경우) 언제든지 DTO에 가까운 매핑 클래스를 만들 수 있습니다.

T4 템플릿을 사용하여 매핑 클래스를 만듭니다.

Pro's - 런타임 매퍼보다 빠른 컴파일 시간에 사람이 읽을 수 있는 코드입니다.코드에 대한 100% 제어(일부 메소드/모뎀 패턴을 사용하여 애드혹 기반으로 기능 확장 가능)

Con's - 특정 속성, 도메인 객체 모음 등 제외, T4 구문 학습

DTO 클래스 내에서 도메인 개체를 매개 변수로 사용하는 생성자를 구현하려면 어떻게 해야 합니까?

이런 식으로 말입니다.

class DTO {

     // attributes 

     public DTO (DomainObject domainObject) {
          this.prop = domainObject.getProp();
     }

     // methods
}

또 다른 가능한 해결책은 http://glue.codeplex.com 입니다.

특징:

  • 양방향 매핑
  • 자동 매핑
  • 서로 다른 유형 간의 매핑
  • 중첩 매핑 및 평탄화
  • 목록 및 배열
  • 관계 확인
  • 매핑 테스트
  • 속성, 필드 및 메서드

객체 대 객체 매핑기인 Otis도 사용할 수 있습니다.개념은 NHibernate 매핑(속성 또는 XML)과 유사합니다.

http://code.google.com/p/otis-lib/wiki/GettingStarted

CodePlex: EntitiesToDTOs에서 호스팅되는 오픈 소스이며 제가 만든 도구를 제안할 수 있습니다.

DTO에서 엔터티로 매핑하거나 그 반대의 경우 확장 메서드에 의해 구현되며, 이들은 각 엔드의 어셈블러 측을 구성합니다.

다음과 같은 코드로 끝납니다.

Foo entity = new Foo();
FooDTO dto = entity.ToDTO();
entity = dto.ToEntity();

List<Foo> entityList = new List<Foo>();
List<FooDTO> dtoList = entityList.ToDTOs();
entityList = dtoList.ToEntities();

또 다른 옵션은 Model Projector를 사용하는 것입니다.가능한 모든 시나리오를 지원하며 설치 공간을 최소화하면서 사용하기가 매우 쉽습니다.

우리는 Factory, Memento, Builder 패턴을 사용할 수 있습니다.DTO에서 도메인 모델 인스턴스를 만드는 방법에 대한 세부 정보를 공장에서 숨깁니다.Memento는 DTO와의 도메인 모델의 직렬화/직렬화를 관리하고 개인 멤버에도 액세스할 수 있습니다.Builder는 유창한 인터페이스로 DTO에서 도메인으로의 매핑을 허용합니다.

언급URL : https://stackoverflow.com/questions/678217/best-practices-for-mapping-dto-to-domain-object

반응형