Является ли «Mapper» допустимым шаблоном дизайна или это вариант «Factory»?

37

Обычный шаблон, который я вижу, - это то, что известно как Mapperшаблон (не путать с DataMapperкоторым, что-то совсем другое), который принимает в качестве аргумента некий «необработанный» источник данных (например, ADO.NET DataReaderили DataSet) и сопоставляет поля с свойства объекта бизнес / домен. Пример:

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

Идея заключается в том, что ваш шлюз / DAO / репозиторий / и т.д. вызовет Mapper прежде, чем он вернется, так что вы получите богатый бизнес-объект по сравнению с базовым контейнером данных.

Однако, похоже, это связано, если не идентично, с шаблоном Factory (в любом случае на языке DDD), который создает и возвращает объект домена. Википедия говорит, что это: фабрика DDD:

Фабрика: методы для создания объектов домена должны делегироваться специализированному объекту Фабрики, так что альтернативные реализации могут быть легко взаимозаменяемы.

Из этой цитаты единственное различие, о котором я мог подумать, заключается в том, что можно задавать параметризацию фабрики в стиле DDD, чтобы она могла возвращать объект специального типа, если возникнет такая необходимость (например, BusinessCustomer или ResidentialCustomer), в то время как «Mapper» связан с определенным классом. и только делает перевод.

Так есть ли разница между этими двумя шаблонами или они по сути одно и то же с разными именами?

Уэйн Молина
источник
Отличается ли это от ORM и если да, то в чем разница?
JB King
ORM автоматически обрабатывают сопоставление для вас - это больше для сценария, в котором вы не можете использовать ORM (или должны написать свой собственный слой данных / тонкий ORM)
Уэйн Молина,
1
Я действительно изо всех сил пытаюсь понять, что DataMapper - это «нечто совершенно другое».
фунтовые
Возможно, я ошибаюсь - я думал, что DataMapperшаблон сделал сам доступ к базе данных, в то время как этот «Mapper» не извлекает базу данных, а просто конвертирует некоторый набор результатов в объект.
Уэйн Молина
martinfowler.com/eaaCatalog/dataMapper.html Я понимаю, что вы имеете в виду, но, читая последний абзац, речь пойдет о праве. Посмотрите на каталог PEAA. martinfowler.com/eaaCatalog/index.html . То, что вы описываете, безусловно, является типом Mapper и более точно соответствует DataMapper, чем остальные.
фунтовые

Ответы:

23

Хотя я впервые слышу о шаблоне Mapper, для меня он больше похож на шаблон Builder, а не на Factory.

В шаблоне Factory вы инкапсулируете логику для создания объектов ряда связанных классов. Основным примером будет ситуация, когда вам нужно создать объект определенного подкласса некоторого абстрактного базового класса в зависимости от некоторых параметров. Таким образом, Factory всегда возвращает указатель или ссылку на базовый класс, но на самом деле создает объект соответствующего производного класса на основе заданных вами параметров.

Напротив, класс Builder всегда создает объекты одного и того же класса. Вы бы использовали его, если создание объекта сложное, например, его конструктор принимает множество аргументов, но не все из них могут быть доступны мгновенно. Таким образом, объект построителя может быть местом, в котором хранятся значения для аргументов конструктора, пока вы не получите их все и не будете готовы создать «продукт», или он может предоставить разумные значения по умолчанию и позволить вам указывать только те аргументы, значения которых вам нужны менять. Типичный пример использования шаблона Builder - создание объектов, которые могут вам понадобиться в модульном тесте, чтобы избежать загромождения тестового кода всей логикой создания.

Для меня Mapper звучит как вариант Builder, где параметры конструктора представлены в виде записи в базе данных или какой-то другой «необработанной» структуры данных.

Дима
источник
Хм, я слышал о Строителе, но не знал на 100% о том, что это повлекло - это помогло прояснить ситуацию! Похоже, что основное отличие заключается в том, что Factory возвращает интерфейсный / абстрактный класс, который на самом деле является конкретным классом, основанным на параметрах (если это имело смысл), в то время как Builder / Mapper берет фактические данные и отображает их в свойствах без особой (если вообще есть) логики ?
Уэйн Молина
1
@ Вайн М: в значительной степени. Хотя в Builder может быть много логики, потому что сопоставление данных со свойствами может вообще не быть прямым. Фактически, компоновщик может содержать других компоновщиков для построения параметров. :)
Дима
5
Шаблон Builder позволяет вам поместить всю информацию, необходимую для построения сложного (обычно неизменяемого) объекта во времени, а затем создать экземпляр объекта в конце процесса. Это не то, что здесь происходит.
фунтовые
+1 Согласился, что это разумный подход, имеющий отдельный класс 'mapper', который выступает в качестве посредника между объектами DTO и объектами модели предметной области. Это также удобно, когда объекты модели домена должны быть переведены в какое-то особое состояние при создании (например, интерфейс .NET ISupportInitialize).
MattDavey
@pdr, я согласен, что Mapper не совсем похож на конструктор, потому что все данные доступны сразу. Но это очень похоже, потому что он строит только один тип объектов.
Дима
8

Единственная общая черта Mapper, Builder и Factory - это то, что они предоставляют «созданный продукт» - и экземпляр объекта типа. Чтобы избежать путаницы, я имею в виду следующие обсуждения для их соответствующего определения.

  1. Mapper - близко к тому, что объясняется здесь: http://www.codeproject.com/KB/library/AutoMapper.aspx . Это не совсем то же самое, что и выше - но ближе всего я нашел о картографе.

  2. Строитель - как определено здесь: http://www.oodesign.com/builder-pattern.html

  3. Фабрика - определяется здесь: http://www.oodesign.com/factory-pattern.html

Картограф по сути является конструктором наизнанку. Предположим, какое-то время, если у вас нет маппера - когда вам все равно нужно много наборов параметров, все они являются аргументами конструктора. Теперь, когда вещи развиваются, некоторые приложения не знают о дополнительных атрибутах, которые нужно указывать в конструкторе, где его вычисляют или используют по умолчанию. Критическим моментом является то, что mapper может сделать это для вас - и было бы более полезно, если бы он имел связь с внешними объектами, чтобы решить такой алгоритм построения.

Строитель сильно отличается от картографа. Строитель необходим, когда полный объект состоит из множества частей объекта. Это своего рода сборка объектов путем соединения многих частей. Даже инициализация отдельных частей объекта связана с существованием других частей.

Заводские шаблоны вначале выглядят очень просто. Возвращает вновь построенные объекты. Если какой-либо обычный конструктор может дать мне полностью функциональный экземпляр, используя оператор, как new ()? зачем мне завод, который дает мне такие же результаты?

Однако использование фабричного паттерна обычно очень специфично; хотя чаще всего не отображается в литературе, где это применяется. Обычно приложение создает фабрику, которая используется для различных объектов, которым необходимо создавать такие объекты продукта во время выполнения. Когда создается много таких продуктов, метод Factory позволяет создавать объекты на основе определенной политики, например, можно принудительно установить определенный шаблон, который используется методом фабрики при создании всех объектов. Это не похоже на метод построения; здесь продукт только один (и независимый). Это также не похоже на картограф; здесь внешний набор данных для создания объекта согласно клиенту фактически минимален. Фабричный шаблон действительно обеспечивает (как следует из названия) последовательно аналогичные объекты продукта!

Dipan.

Дипан Мехта
источник
4

Просматривая ответы, я вижу, что все респонденты дают семантически неправильные ответы. Я думаю, что это потому, что вы слишком сосредоточены на вопросе, который сосредоточен на том, как картостроитель связан с фабрикой или строителем.

Когда на самом деле Mapper НЕ похож на фабрику или строителя. Mapper больше всего похож на шаблон адаптера (на языке GoF). Шаблон адаптера обеспечивает функциональность для преобразования одного представления в другое. OP ссылался на DataSet и DataReader в ADO.NET - ну как насчет SqlDataAdapter? Ответ в названии. Mapper - это новое название для чего-то, о чем старые программисты знали давно: адаптеры.

Mapper преобразует одно представление в другое - само определение шаблона адаптера.

Рувим Сото
источник
1

То, что вы делаете здесь, на самом деле является своего рода преобразованием типов (вы преобразуете свои необработанные данные в бизнес-объект). Вы можете использовать Factory Pattern для точного выполнения этого (т. Е. Преобразования типов), так что да, каким-то образом ваш класс является фабрикой (хотя я бы использовал статическую фабрику для этого).

Оливер Вейлер
источник
0

Строители инкапсулируют сложную бизнес-логику для построения объекта. Картограф, с другой стороны, должен просто копировать поля из одного в другое.

Например, сопоставление объекта «Сотрудник базы данных» с объектом «Сотрудник домена», сопоставление объекта «Сотрудник домена» с клиентским контрактом.

С другой стороны, строители принимают множество бизнес-решений для создания объекта. С точки зрения единой ответственности это имеет смысл.

user95940
источник