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 MyPoint2D과 class YourPoint2D그들이 동일한 정의를 경우에도 별도의 종류는. 원하는 유형이 " x필드와 필드를 가진 일부 익명의 것 y"(즉, 레코드 )이면 운이 좋지 않습니다. 당신은을 설정하고자 할 때 그래서 YourPoint2D에 MyPoint2D, 당신은 세 가지 옵션이 있습니다 :

  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.