AutoMapper와 같은 것이 필요하다는 것은 디자인이 좋지 않다는 것을 나타내는 것이 잘못입니까?


35

Automapper 는 .Net에 대한 "객체-객체 매퍼 (object-object mapper)"입니다. 이는 객체를 클래스에서 같은 것을 나타내는 다른 클래스로 복사하는 것을 의미합니다.

이것이 왜 유용한가? 클래스의 복제가 유용하고 좋은 디자인입니까?


약간의 참조 : devtrends.co.uk/blog/… 특히 "자동 매퍼 를 사용할 수없는 이유"섹션을 읽으십시오.
Jani Hyytiäinen

답변:


28

빠른 구글 검색은이 예를 보여 주었다 :

http://www.codeproject.com/Articles/61629/AutoMapper

AutoMapper의 완벽하게 유효한 사용법을 보여줍니다. 이는 열악한 디자인의 예가 아닙니다. 계층화 된 응용 프로그램에서 데이터 또는 비즈니스 계층에 개체가있을 수 있으며 때로는 해당 데이터 개체의 특성 중 일부만 또는 UI 계층에서 해당 개체에 대한보기 만 필요할 수도 있습니다. 따라서 UI에 필요한 속성이 아닌 객체를 포함하는 뷰 모델을 작성하고 AutoMapper를 사용하여 해당 객체의 컨텐츠에 상용구 코드를 줄이십시오.

이러한 상황에서 "보기 개체"는 원래 클래스의 복제본이 아닙니다. 그들은 다른 방법과 아마도 몇 가지 중복 속성을 가지고 있습니다. 그러나 UI 표시 목적으로 만 해당 뷰 객체를 사용하고 데이터 조작이나 비즈니스 운영에 오용하지 않는 한 괜찮습니다.

이에 대한 이해를 돕기 위해 읽을 수있는 또 다른 주제는 CRUD와 달리 Fowlers Command Query Responsibility Segregation 패턴입니다. 데이터를 쿼리하고 데이터베이스에서 업데이트하기위한 서로 다른 개체 모델이 적합한 상황을 보여줍니다. 여기서 한 객체 모델에서 다른 객체 모델로의 매핑은 AutoMapper와 같은 도구로 수행 할 수도 있습니다.


1
첫 번째 예와 관련하여 객체를 복제하는 대신 객체를 작성할 수 없습니까? 이 경우 UI 객체는 원래 데이터 객체에 대한 참조를 가지며 필요한 요소 만 노출합니다. 말이되지 않습니까?
static_rtti

1
이론적으로 @static_rtti 예,하지만 원래 클래스가 공개 또는 어셈블리에 노출되는 것을 원하지 않을 수도 있습니다.
Jalayn

2
@static_rtti : 그렇습니다. 그것은 완벽하게 유효한 다른 접근법입니다. 이 두 디자인의 주요 차이점은 데이터 / 속성의 수명입니다. 복사본을 사용하면 원본 데이터를 참조하지 않는 속성을 사용하여 데이터의 스냅 샷을 제공 할 수 있습니다. 두 가지 방법 모두 장단점이 있지만 IMHO는 일반적으로 "더 나쁘거나 더 나쁜"것은 없습니다. 또한 성능에 대한 고려 사항이있을 수 있으며 이는 결정에 영향을 줄 수도 있고 사용하지 않을 수도 있습니다.
Doc Brown

3
가능한 한 많이 분리하는 것이 좋습니다. 소규모 프로젝트에도 특히 유리하기 때문에가 아니라 프로젝트가 커지기 때문입니다.
Tamás Szelei

6
@fish : 대부분 동의합니다. 디커플링은 종종 좋은 생각이지만 IMHO는 단순하게 유지하는 것이 멀티 레이어 수퍼 디커플링을위한 디커플링 방식보다 중요합니다. 어려운 부분은 리팩토링을 시작해야하는 프로젝트가 성장하는 동안 요점을 놓치지 않아야합니다.
Doc Brown

45

클래스의 복제가 유용하고 좋은 디자인입니까?

데이터 계층에서 사용되는 것과 동일한 클래스를 사용하는 대신 UI 계층에서 별도의 뷰 모델 클래스를 사용하는 것이 좋습니다. UI / 웹 페이지는 데이터 엔터티와 엄격하게 관련되지 않은 다른 정보를 표시해야 할 수도 있습니다. 이 추가 클래스를 만들면 시간이 지남에 따라 요구 사항이 변경 될 때 UI를 쉽게 조정할 수 있습니다.

AutoMapper를 사용하는 한 개인적으로 3 가지 이유로 피합니다.

보다 일반적인 자동 실패

AutoMapper는 속성간에 자동으로 매핑되므로 한 클래스에서 다른 클래스가 아닌 속성 이름을 변경하면 속성 매핑이 건너 뜁니다. 컴파일러는 모른다. 오토 매퍼는 상관하지 않습니다.

정적 분석 부족

따라서 처리 할 큰 코드 기반이 주어졌습니다. 백만 개의 속성을 가진 백만 개의 클래스가 있습니다. 많이 사용되지 않거나 중복 된 것처럼 보입니다. Visual Studio의 "모든 참조 찾기"도구를 사용하면 속성이 사용되는 위치를 확인하고 전체 응용 프로그램이 어떻게 연결되는지에 대한지도를 작성할 수 있습니다. 그러나 Automapper가 사용 중이므로 속성의 절반에 대한 명시 적 참조는 없습니다. 내 직업은 이제 훨씬 더 어려워졌습니다.

복잡성을 증가시키는 최신 요구 사항

Automapper는 ONE 클래스에서 다른 클래스로 값을 복사하는 것만으로도 훌륭하고 멋집니다. 응용 프로그램의 다른 부분에서 값을 가져와야 할 수도 있습니다 (아마 로그인 한 사용자 또는 기타 상황에 따라 다름)?

응용 프로그램 시작시 일대일 클래스 매핑을 생성하는 AutoMapper의 패턴은 이러한 상황 별 변경에 적합하지 않습니다. 그렇습니다. 아마도 그것을 작동시키는 방법이있을 것입니다. 그러나 저는 보통 스스로 논리를 직접 작성하는 것이 더 깨끗하고 단순하며 표현력이 좋습니다.

요약하면, Automapper에 도달하여 한 클래스를 다른 클래스에 수동으로 맵핑하는 30 초를 절약하기 전에 이에 대해 생각해보십시오.

프로그래밍은 다른 사람에게 컴퓨터가 원하는 것을 알려주는 기술입니다. -도널드 크 누스

이를 염두에두고 "오토 매퍼가 오늘 도움이됩니까? 내일이 되겠습니까?"


[유행 웹 개발자라면] REST 웹 서비스를 작성하는 경우 JavaScript 객체 모델이 .NET 객체 모델과 일치하는지 항상 모든 속성을 확인하는 경향이 있습니까?
Den

3
@ 덴-예. 그리고 모든 속성이 올바른지 확인하기 위해 테스트를 작성합니다 (예 : 테스트에 다른 계층으로 전파되지 않는 한 곳에 추가 한 속성이 표시됨)
gbjbaanb

@gbjbaanb 아마도 리플렉션을 사용하여 일반적인 방법 으로이 유효성 검사를 수행합니다. 아마도 AutoMapper를 확장하여 유효성 검사를 추가 할 가능성을 모색 할 것입니다. 많은 수동 할당을 피할 입니다.
Den

전적으로 당신과 동의하고 매우 간단한 응용 프로그램만이 자동 매퍼를 사용할 수 있다고 생각하지만 상황이 복잡해질 때 자동 매퍼에 대한 새로운 구성을 작성 해야하는 이유는 수동 매퍼 도우미 또는 서비스에 작성하지 않는 이유입니다.
ahmedsafan86

21

내 경험상 누군가가 '너무 많은 상용구'에 대해 불평하고 AutoMapper를 사용하고 싶을 때 다음 중 하나였습니다.

  1. 그들은 같은 코드를 반복해서 작성하는 것이 짜증나게합니다.
  2. 그들은 게으르고 Ax = Bx하는 코드를 작성하고 싶지 않습니다.
  3. 실제로 Ax = Bx를 반복해서 쓰는 것이 좋은 아이디어인지 생각한 다음 작업에 적합한 코드를 작성해야한다는 압박을 너무 많이받습니다.

하나:

  1. 반복을 피하는 것이 중요하다면 객체 나 메소드를 만들어 추상화 할 수 있습니다. AutoMapper가 필요하지 않습니다.
  2. 게으 르면 게으 르며 AutoMapper의 작동 방식을 배우지 못합니다. 대신, '우연히 프로그래밍'패턴을 채택하고 AutoMapper 프로파일에서 비즈니스 로직을 작성하는 끔찍한 코드를 작성합니다. 이 경우 프로그래밍에 대한 태도를 바꾸거나 직업으로해야 할 일을 찾아야합니다. AutoMapper가 필요하지 않습니다.
  3. 시간이 너무 많이 걸리면 문제는 프로그래밍 자체와 관련이 없습니다. AutoMapper가 필요하지 않습니다.

정적으로 유형이 지정된 언어를 선택한 경우 해당 언어를 활용하십시오. AutoMapper와 같은 리플렉션 및 마법 API의 과도한 사용으로 인한 실수를 방지하는 데 도움이되는 언어로 컨트롤을 우회하려는 경우 이는 요구에 맞지 않는 언어를 선택했음을 의미합니다.

또한 Microsoft가 C #에 기능을 추가했다고해서 모든 상황에서 공정한 게임이거나 최상의 방법을 지원한다는 의미는 아닙니다. 예를 들어 리플렉션과 '동적'키워드는 필요한 것만으로는 달성 할 수없는 경우에 사용해야합니다. AutoMapper는 솔루션 없이는 해결할 수없는 사용 사례를위한 솔루션이 아닙니다.

그렇다면 클래스 복제가 나쁜 디자인입니까? 반드시 그런 것은 아닙니다.

AutoMapper가 나쁜 생각입니까? 네 그럼요.

AutoMapper의 사용은 프로젝트의 시스템 결함을 나타냅니다. 자신에게 필요한 것을 발견하면 디자인을 중단하고 생각하십시오. 항상 더 좋고, 더 읽기 쉽고, 유지 보수가 쉽고, 버그가없는 디자인을 찾을 수 있습니다.


1
잘 말
했어요.

2
나는 이것이 매우 오래된 스레드라는 것을 알고 있지만 1에 동의하지 않아야합니다. 매핑을 추상화하는 방법을 만들 수 없습니다. 1 수업을 할 수 있지만 2가있는 경우 2 개의 메소드가 필요합니다. 3-3 가지 방법. AM을 사용하면 한 줄의 코드-매핑 정의입니다. 또한 10 가지 하위 유형 DTO로 채워진 List <BaseType>이있는 시나리오와 실제로 어려움을 겪었습니다. 이를 맵핑하려면 필드 값을 복사하는 유형 및 메소드 켜기가 필요합니다. 필드 중 하나를 별도로 매핑해야하는 경우 어떻게해야합니까? 간단한 수업이 거의없는 경우에만 답이 좋습니다. 더 복잡한 시나리오에서 AutoMapper가 승리합니다.
user3512524

1
(char limit) AM의 유일한 함정은 다른 클래스가 아닌 한 클래스에서 속성 이름을 변경할 가능성이라고 생각합니다. 그러나 실제로 설계가 완료된 후 얼마나 자주 수행합니까? 또한 리플렉션을 사용하고 속성 이름을 비교하는 일반적인 테스트 방법을 작성할 수 있습니다. 모든 도구와 마찬가지로 AM은 모든 상황에서 맹목적으로가 아니라 올바르게 사용해야합니다. 그러나 "사용해서는 안된다"고 말하는 것은 잘못입니다.
user3512524

7

여기에 더 깊은 문제가 있습니다 : 예를 : C # 및 Java는 모든 유형의 이름이 아닌 구조에 의해 구별 할 수 있어야합니다 / 대부분의 주장 사실 class MyPoint2Dclass YourPoint2D그들이 동일한 정의를 경우에도 별도의 종류는. 원하는 유형이 " x필드와 필드를 가진 일부 익명의 것 y"(즉, 레코드 )이면 운이 좋지 않습니다. 당신은을 설정하고자 할 때 그래서 YourPoint2DMyPoint2D, 당신은 세 가지 옵션이 있습니다 :

  1. 지루하고 반복적이며 평범한 상용구를 작성하십시오. this.x = that.x; this.y = that.y
  2. 어떻게 든 코드를 생성하십시오.
  3. 반사를 사용하십시오.

선택 1은 소량으로도 충분하지만 매핑해야 할 유형의 수가 많을 때 신속하게 집안일이됩니다.

코드 2를 생성하기 위해 빌드 프로세스에 추가 단계를 추가하고 팀 전체가 메모를 받아야하기 때문에 선택 2는 바람직하지 않습니다. 최악의 경우 자체 코드 생성기 또는 템플릿 시스템을 롤링해야합니다.

그것은 당신에게 반성을 남깁니다. 직접 할 수도 있고 AutoMapper를 사용할 수도 있습니다.


2

Automapper는 황제가 말 그대로 엉덩이 주위를 돌고있는 라이브러리 / 도구 중 하나입니다. 화려한 로고를지나 치면 더 나은 결과를 얻을 수없는 수동 작업을 수행 할 수 없습니다.

자동 매핑 멤버를 암시하는 방법을 완전히 확신하지는 못하지만 추가 런타임 논리와 가능한 반영이 필요할 가능성이 큽니다. 시간을 절약하는 대신 성능이 크게 저하 될 수 있습니다. 반면 수동 매핑은 힌트를 컴파일 시간 전에 실행합니다.

AutoMapper에 실마리가없는 경우 코드 및 설정 플래그를 사용하여 매핑을 구성해야합니다. 모든 설정 및 코드 작업을 귀찮게하려면 수동 매핑보다 얼마나 많은 비용을 절약해야하는지 질문해야합니다.

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