"매퍼"가 유효한 디자인 패턴입니까 아니면 "공장"패턴의 변형입니까?


37

내가 볼 수있는 일반적인 패턴은 일종의 "원시"데이터 소스 (예 : ADO.NET 또는 )를 인수로 사용 하여 필드를 매핑하는 Mapper패턴 ( DataMapper전적으로 다른 것과 혼동하지 말 것)으로 알려진 패턴 입니다. 비즈니스 / 도메인 개체의 속성 예:DataReaderDataSet

class PersonMapper
{
    public Person Map(DataSet ds)
    {
        Person p = new Person();
        p.FirstName = ds.Tables[0].Rows[0]["FirstName"].ToString();
        // other properties...
        return p;
    }
}

아이디어는 Gateway / DAO / Repository / etc입니다. 반환되기 전에 매퍼를 호출하므로 기본 데이터 컨테이너에 비해 풍부한 비즈니스 개체를 얻게됩니다.

그러나 이것은 동일하지는 않지만 도메인 패턴을 구성하고 반환하는 팩토리 패턴 (DDD 용어에서는 어쨌든)과 관련이있는 것 같습니다. Wikipedia는 다음과 같이 말합니다 : DDD 팩토리 :

팩토리 : 도메인 객체를 생성하는 메소드는 대체 구현을 쉽게 교환 할 수 있도록 특수 팩토리 객체에 위임해야합니다.

그 견적에서 내가 생각할 수있는 유일한 차이점은 DDD 스타일 팩토리를 매개 변수화 할 수 있다는 것입니다. 필요한 경우 (예 : BusinessCustomer 대 ResidentialCustomer) "매퍼"가 특정 클래스에 입력되면 특수 유형의 객체를 반환 할 수 있습니다 그리고 단지 번역을한다.

이 두 패턴 사이에 차이점이 있습니까? 아니면 본질적으로 다른 이름을 가진 동일한 것입니까?


이것이 ORM과 다른가? 그렇다면 차이점은 어디에 있습니까?
JB King

ORM은 자동으로 매핑을 처리합니다. 이는 ORM을 사용할 수없는 (또는 자체 데이터 계층 / 씬 ORM을 작성해야하는) 시나리오에 더 적합합니다.
Wayne Molina

1
나는 DataMapper가 어떻게 "전적으로 다른 것"인지 알기 위해 고심하고 있습니다.
pdr

어쩌면 내가 틀렸을 수도있다- DataMapper이 "매퍼 (Mapper)"는 데이터베이스에서 가져 오지 않고 어떤 종류의 결과 집합을 객체로 변환하는 반면 패턴은 데이터베이스 액세스 자체를 수행 했다고 생각했다 .
웨인 몰리나

martinfowler.com/eaaCatalog/dataMapper.html 당신이 무슨 뜻인지 알지만 마지막 단락을 읽으면 그것은 옳습니다. PEAA 카탈로그를보십시오. martinfowler.com/eaaCatalog/index.html . 당신이 설명하는 것은 확실히 일종의 매퍼이며, 나머지보다 DataMapper에 더 가깝습니다.
pdr

답변:


23

이것이 매퍼 패턴에 대해 처음 듣는 것은 아니지만, 팩토리보다는 빌더 패턴과 비슷하게 들립니다.

팩토리 패턴에서는 여러 관련 클래스의 객체를 만들기위한 논리를 캡슐화합니다. 가장 좋은 예는 일부 매개 변수에 따라 추상 기본 클래스의 특정 서브 클래스의 오브젝트를 작성해야하는 상황입니다. 따라서 팩토리는 항상 기본 클래스에 대한 포인터 또는 참조를 반환하지만 실제로는 사용자가 제공 한 매개 변수를 기반으로 적절한 파생 클래스의 객체를 만듭니다.

반대로 Builder 클래스는 항상 같은 클래스의 객체를 만듭니다. 객체 생성이 복잡한 경우이 객체를 사용합니다. 예를 들어 생성자가 많은 인수를 취하지 만 모든 인수를 즉시 사용할 수있는 것은 아닙니다. 따라서 빌더 오브젝트는 생성자 인수에 대한 값을 모두 저장하고 "제품"을 작성할 준비가 될 때까지 생성자 인수의 값을 저장하는 장소이거나 합리적인 기본값을 제공하고 값이 필요한 인수 만 지정할 수 있습니다. 변화. 빌더 패턴의 일반적인 사용 사례는 모든 작성 로직으로 테스트 코드를 어지럽히 지 않도록 단위 테스트에 필요할 수있는 오브젝트를 작성하는 것입니다.

저에게 매퍼는 생성자의 매개 변수가 데이터베이스 레코드 또는 다른 "원시"데이터 구조의 형태로 나타나는 Builder의 변형처럼 들립니다.


흠 나는 빌더에 대해 들었지만 그것이 무엇을 의미하는지 100 % 알지 못했습니다. 가장 큰 차이점은 Factory가 매개 변수를 기반으로 실제 클래스 인 인터페이스 / 추상 클래스를 반환한다는 것입니다. ?
웨인 몰리나

1
@ 와인 M : 거의. 빌더에는 많은 논리가있을 수 있지만, 데이터를 특성에 맵핑하는 것은 전혀 간단하지 않을 수 있기 때문입니다. 실제로 빌더에는 매개 변수를 빌드하기위한 다른 빌더가 포함될 수 있습니다. :)
Dima

5
빌더 패턴을 사용하면 시간이 지남에 따라 복잡한 (일반적으로 불변의) 오브젝트를 빌드하는 데 필요한 모든 정보를 넣은 다음 프로세스가 끝날 때 오브젝트를 인스턴스화 할 수 있습니다. 그것은 여기서 일어나고있는 것이 아닙니다.
pdr

+1 DTO 개체와 도메인 모델 개체 사이의 중재자 역할을하는 별도의 '매퍼'클래스가있는 합리적인 접근 방식에 동의했습니다. 또한 도메인 모델 개체를 구성 할 때 특정 상태 (예 : .NET ISupportInitialize 인터페이스)로 만들어야하는 경우에도 유용합니다.
MattDavey

@ pdr, 모든 데이터를 한 번에 사용할 수 있기 때문에 매퍼가 빌더와 정확히 일치하지 않는다는 데 동의합니다. 그러나 한 가지 유형의 객체 만 작성하기 때문에 매우 유사합니다.
Dima

8

Mapper, Builder 및 Factory의 유일한 공통점은 "구성된 제품"및 유형의 객체 인스턴스를 제공한다는 것입니다. 혼란을 피하기 위해 각각의 정의에 대해 다음과 같은 토론을 언급하고 있습니다.

  1. 매퍼-http: //www.codeproject.com/KB/library/AutoMapper.aspx에 설명 된 내용에 가깝습니다 . 이것은 위와 정확히 동일하지는 않지만 매퍼에 대해 가장 가깝습니다.

  2. 빌더-여기에 정의 된대로 : http://www.oodesign.com/builder-pattern.html

  3. 공장-여기에 정의되어 있습니다 : http://www.oodesign.com/factory-pattern.html

매퍼는 본질적으로 내부 생성자입니다. 매퍼가없는 경우 잠시 동안 가정하십시오-어쨌든 많은 매개 변수 세트가 필요할 때 모두 생성자의 인수입니다. 이제 상황이 발전함에 따라 일부 응용 프로그램은 생성자에서 계산하거나 기본값을 사용하는 생성자 아래에 필요한 추가 속성을 인식하지 못합니다. 중요한 것은 매퍼 가이 작업을 수행 할 수 있다는 것입니다. 이것이 외부 객체와 연결되어 이러한 알고리즘을 결정하는 것이 더 유용합니다.

빌더는 매퍼와 매우 다릅니다. 빌더는 오브젝트의 많은 부분을 사용하여 완전한 오브젝트를 구성 할 때 필수적입니다. 많은 부분을 함께 끼워서 물건을 조립하는 것입니다. 개별 부품 객체의 초기화조차도 다른 부품의 존재와 관련이 있습니다.

팩토리 패턴은 처음부터 매우 단순 해 보입니다. 새로 생성 된 객체를 반환합니다. 일반 생성자가 new ()와 같은 연산자를 사용하여 완전한 기능을 갖춘 인스턴스를 제공 할 수 있습니까? 동일한 결과를 제공하는 공장이 필요한 이유는 무엇입니까?

그러나 팩토리 패턴의 사용법은 일반적으로 매우 구체적입니다. 가장 자주 적용되는 문헌에는 표시되지 않습니다. 일반적으로 응용 프로그램은 실행 중에 이러한 제품 개체를 만들어야하는 다양한 개체와 공유되는 팩토리를 만듭니다. 이러한 많은 제품이 생성 될 때 팩토리 메소드를 사용하면 특정 정책 을 기반으로 오브젝트를 작성할 수 있습니다. 예를 들어, 모든 오브젝트가 작성 될 때 팩토리 메소드가 사용하는 특정 템플리트를 강제 할 수 있습니다. 이것은 빌더 메소드와 같지 않습니다. 여기서 제품 출력은 하나뿐입니다 (독립적). 이것은 또한 매퍼와는 다릅니다. 여기서 클라이언트에 따라 객체를 생성하는 외부 데이터 세트는 실제로 최소입니다. 팩토리 패턴은 이름에서 알 수 있듯이 지속적으로 유사한 제품 객체를 제공합니다!

디판



4

답변을 살펴보면 응답자가 의미 적으로 잘못된 답변을 제공하는 것을 볼 수 있습니다. 나는 이것이 당신이 매퍼가 공장이나 건축업자와 어떻게 관련되어 있는지에 초점을 맞춘 질문에 너무 집중했기 때문이라고 생각합니다.

실제로 매퍼는 공장이나 건축업자와 유사하지 않습니다. 매퍼는 어댑터 패턴 과 가장 유사합니다 (GoF 용어 사용). 어댑터 패턴은 하나의 표현을 다른 표현으로 변환하는 기능을 제공합니다. OP는 ADO.NET의 DataSet 및 DataReader를 참조했습니다. SqlDataAdapter는 어떻습니까? 답은 이름입니다. Mapper는 구형 프로그래머가 오랫동안 알고있는 새로운 이름 인 어댑터입니다.

매퍼는 한 표현을 다른 표현, 즉 어댑터 패턴의 정의로 변환합니다.


1

여기서하는 일은 실제로 일종의 유형 변환입니다 (원시 데이터를 비즈니스 객체로 변환). 팩토리 패턴을 사용하여 정확히 수행 할 수 있습니다 (예 : 유형 변환). 그렇습니다. 어떻게 든 클래스는 팩토리입니다 ( 정적 팩토리 를 사용하지만 ).


0

빌더는 복잡한 비즈니스 로직을 캡슐화하여 오브젝트를 빌드합니다. 반면 매퍼는 필드를 서로 복사해야합니다.

예를 들어 지도 도메인 직원 개체에 대한 데이터베이스 직원 개체에서, 지도 클라이언트 계약에 도메인 직원 Object에서.

반면에 빌더 는 오브젝트 를 빌드 하기 위해 여러 비즈니스 결정을 호스트 합니다. 단일 책임 관점에서 이것은 의미가 있습니다.

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