문제

매핑과 관련된 많은 질문을 보았습니다 DTOS 도메인 객체에 대해서는 그들이 내 질문에 대답했다고 생각하지 않았습니다. 나는 전에 많은 방법을 사용했고 내 의견을 가지고 있지만 조금 더 구체적인 것을 찾고 있습니다.

그 상황:

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

내 질문은 : DTO와 도메인 객체를 어떻게 연결해야합니까?

나의 첫 번째 반응은 a를 사용하는 것입니다 Fowler, DTO 패턴 유형 솔루션. 나는 이것을 여러 번 보았고 그것은 나에게 옳다고 느낀다. 도메인 객체에는 DTO에 대한 참조가 포함되어 있지 않습니다. 도메인 개체에서 DTO를 생성하기 위해 외부 엔티티 ( "매퍼"또는 "어셈블러")가 호출됩니다. 일반적으로 an이 있습니다 ORM 도메인 객체 측면에서. 이것의 단점은 "맵퍼"가 실제 상황에서 매우 복잡해지는 경향이 있으며 매우 취약 할 수 있다는 것입니다.

또 다른 아이디어는 도메인 객체가 DTO를 "포함"하는 것입니다. 도메인 객체 속성은 내부적으로 DTO 속성을 참조하고 요청하면 DTO를 반환 할 수 있습니다. 나는 이것에 아무런 문제가 없지만 잘못된 느낌입니다. 사람들이 사용하는 기사를 보았습니다 nhibernate 이 방법을 사용하는 것처럼 보였습니다.

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

도움이 되었습니까?

해결책

단일 매핑 만 지원할 때 도메인과 DTO 사이에있는 맵퍼를 갖는 이점은 맵핑 횟수가 증가함에 따라 도메인에서 해당 코드를 분리하면 도메인을 더 간단하고 leger로 유지하는 데 도움이됩니다. 당신은 더 많은 무게로 도메인을 어지럽히지 않을 것입니다.

개인적으로, 나는 도메인 엔티티에서 매핑을 보관하고 "관리자 / 서비스 계층"이라고 부르는 것에 책임을집니다. 이것은 응용 프로그램과 Respository (IES) 사이에있는 계층이며 워크 플로 조정과 같은 비즈니스 로직을 제공합니다 (A를 수정하는 경우 B를 수정해야 할 수도 있으므로 서비스 A가 서비스 B와 작동합니다).

가능한 결말 형식이 많으면 방문자 패턴을 사용할 수있는 플러그 가능한 포맷터를 만드는 것을 살펴볼 수 있지만, 예를 들어 엔터티를 변형시킬 수 있지만 아직이 복잡한 것이 필요하지 않았습니다.

다른 팁

당신은 다음과 같은 오고판을 사용할 수 있습니다 Jimmy Bogard가 쓴 것 객체 사이에 연결되지 않으며 지명이 지정되는 이름 지정 규칙에 의존합니다.

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

Pro-- 컴파일 타임에 사용할 수있는 휴먼 읽기 가능한 코드는 런타임 맵퍼보다 빠릅니다. 코드에 대한 100% 제어 (부분 메소드/템플릿 패턴을 사용하여 임시 기준으로 기능을 확장 할 수 있음)

CON- 특정 속성, 도메인 객체의 컬렉션 등을 제외하고 T4 구문 학습.

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

특징:

  • 양방향 매핑
  • 자동 매핑
  • 다른 유형간에 매핑
  • 중첩 된 매핑 및 평평한
  • 목록 및 배열
  • 관계의 검증
  • 매핑 테스트
  • 속성, 필드 및 방법

매개 변수로 도메인 객체를 취하는 DTO 클래스 내부에서 생성자를 구현하는 방법은 무엇입니까?

말해 ... 이렇게

class DTO {

     // attributes 

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

     // methods
}

객체 투 객체 매퍼 인 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();

왜 우리는 이것을 그렇게 할 수 없습니까?

class UserDTO {
}

class AdminDTO {
}

class DomainObject {

 // attributes
 public DomainObject(DTO dto) {
      this.dto = dto;
 }     

 // methods
 public function isActive() {
      return (this.dto.getStatus() == 'ACTIVE')
 }

 public function isModeratorAdmin() {
      return (this.dto.getAdminRole() == 'moderator')
 }

}


userdto = new UserDTO();
userdto.setStatus('ACTIVE');

obj = new DomainObject(userdto)
if(obj.isActive()) {
   //print active
}

admindto = new AdminDTO();
admindto.setAdminRole('moderator');

obj = new DomainObject(admindto)
if(obj.isModeratorAdmin()) {
   //print some thing
}

@frederikprijck (또는) 누군가 : 제안하십시오. 위의 예에서 DomainObject는 DTO에 따라 다릅니다. 이런 식으로 나는 dto <-> domainobject를 매핑하는 코드를 피할 수 있습니다.

아니면 DomainObject 클래스가 DTO 클래스를 확장 할 수 있습니까?

또 다른 옵션은 사용하는 것입니다 ModelProjector. 가능한 모든 시나리오를 지원하며 최소한의 발자국으로 사용하기가 매우 쉽습니다.

우리는이를 위해 공장, 기념품 및 빌더 패턴을 사용할 수 있습니다. 공장 DTO에서 도메인 모델 인스턴스를 만드는 방법에 대한 세부 사항을 숨 깁니다. Memento는 도메인 모델의 DTO에서/로부터의 직렬화/사제화를 관리하며 개인 구성원에 액세스 할 수도 있습니다. 빌더는 유창한 인터페이스를 사용하여 DTO에서 도메인으로의 매핑을 허용합니다.

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

다른 곳에 매핑을 유지하는 것은 유일한 대안이 될 것입니다. 그러나 어디로 가야합니까? 나는 매핑 객체/서비스를 소개하려고 시도했지만 결국 말을하고 끝난 후에는 과잉 가전기처럼 보였습니다 (아마도). 나는 소규모 프로젝트를 위해 Automapper와 같은 성공을 거두었지만 Automapperp와 같은 도구에는 자체 함정이 있습니다. Automapper의 매핑은 코드의 나머지 부분과 완전히 분리되어 있기 때문에 매핑과 관련된 문제를 찾기가 매우 어려웠습니다 ( "우려의 분리"가 아니라 "Godforkaken 매핑은 어디에 있습니까?) 때로는 추적하기가 어려울 수 있습니다. Automapper는 사용이 없다고 말할 수는 없습니다. 나는 단지 매핑이 문제를 피하기 위해 가능한 한 명백하고 투명해야한다고 생각합니다.

매핑 서비스 계층을 만드는 대신 DTO 내부에 매핑을 유지하는 데 많은 성공을 거두었습니다. DTOS Alway는 응용 프로그램의 경계에 앉아 있으므로 비즈니스 대상을 인식하고지도에서지도하는 방법을 알아낼 수 있습니다. 매핑 횟수가 합리적인 양으로 늘어나더라도 깨끗하게 작동합니다. 모든 매핑은 한 곳에 있으며 데이터 계층, 부패 방지 계층 또는 프리젠 테이션 레이어 내부에 많은 맵핑 서비스를 관리 할 필요가 없습니다. 대신, 매핑은 요청/응답과 관련된 DTO에 위임 된 구현 세부 사항 일뿐입니다. 직렬화기는 일반적으로 와이어를 통해 보낼 때 특성과 필드 만 직렬화하므로 문제를 해결하지 않아야합니다. 개인적으로, 나는 이것을 가장 깨끗한 옵션임을 발견했으며, 내 경험상 큰 코드 기반에서 잘 확장됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top