Automapper - это «объект-объектный маппер» для .Net, что означает копирование объектов из класса в другой класс, представляющий то же самое.
Почему это всегда полезно? Является ли дублирование классов полезным / хорошим дизайном?
Automapper - это «объект-объектный маппер» для .Net, что означает копирование объектов из класса в другой класс, представляющий то же самое.
Почему это всегда полезно? Является ли дублирование классов полезным / хорошим дизайном?
Ответы:
Быстрый поиск в Google показал этот пример:
http://www.codeproject.com/Articles/61629/AutoMapper
демонстрируя совершенно правильное использование AutoMapper, которое определенно не является примером плохого дизайна. В многоуровневом приложении у вас могут быть объекты в ваших данных или бизнес-уровне, и вам иногда требуется просто подмножество атрибутов этих объектов данных или какой-то вид на них в вашем уровне пользовательского интерфейса. Таким образом, вы создаете модель представления, которая содержит объекты с именно теми атрибутами, которые вам необходимы в вашем пользовательском интерфейсе, не более, и используете AutoMapper, чтобы обеспечить содержание этих объектов с меньшим количеством стандартного кода.
В такой ситуации ваши «объекты просмотра» не являются дубликатами исходного класса. У них разные методы и, возможно, несколько дублирующих атрибутов. Но это нормально, если вы используете это представление объектов только для целей отображения пользовательского интерфейса и не начинаете злоупотреблять ими для манипулирования данными или бизнес-операций.
Еще одна тема, которую вы можете прочитать, чтобы лучше понять это, - это шаблон разделения ответственности командного запроса Фаулера , в отличие от CRUD. Он показывает ситуации, когда различные объектные модели для запроса данных и обновления их в базе данных имеют смысл. Здесь отображение из одной объектной модели в другую также можно выполнить с помощью такого инструмента, как AutoMapper.
Является ли дублирование классов полезным / хорошим дизайном?
Рекомендуется использовать отдельный класс модели представления для использования на уровне пользовательского интерфейса, а не тот же класс, который используется на уровне данных. Ваш пользовательский интерфейс / веб-страница, возможно, должны отображать другие биты информации, которые не связаны строго с объектом данных. Создавая этот дополнительный класс, вы даете себе свободу легко настраивать свой пользовательский интерфейс, поскольку требования со временем меняются.
Что касается использования AutoMapper, я лично избегаю этого по 3 причинам:
Тихие неудачи чаще встречаются
Поскольку AutoMapper сопоставляет свойства автоматически, изменение имени свойства в одном классе, а не в другом, приведет к пропуску отображения свойств. Компилятор не будет знать. Automapper не волнует.
Отсутствие статического анализа
Итак, вы получили большую кодовую базу для работы. Есть миллион классов с миллионами свойств. Много похоже, что они не используются или являются дубликатами. Этот инструмент «Найти все ссылки» в Visual Studio поможет вам увидеть, где используются свойства, и поможет составить карту того, как все приложение соединяется вместе. Но подождите, нет явных ссылок на половину свойств, потому что используется Automapper. Моя работа сейчас намного сложнее.
Поздние требования, которые увеличивают сложность
Automapper отлично работает, когда все, что вы хотите сделать, это скопировать значения из ОДНОГО класса в другой (как это часто бывает при НАЧАЛЕ разработки), но помните те требования, которые со временем меняются? Что если вам теперь нужно получить значения из других частей вашего приложения, возможно, специфичные для пользователя, который вошел в систему, или какое-то другое контекстное состояние?
Шаблон AutoMapper по созданию сопоставлений классов «один-к-одному» при запуске приложения не очень хорошо подходит для такого рода специфичных для контекста изменений. Да, возможно, есть способы заставить это работать, но я обычно нахожу чище, проще и выразительнее, чтобы писать логику самостоятельно.
Таким образом, прежде чем обратиться к Automapper, чтобы сэкономить 30 секунд, вручную сопоставляя один класс с другим, подумайте об этом.
Программирование - это искусство рассказывать другому человеку, чего хочет компьютер. - Дональд Кнут
Имея это в виду, спросите себя: "AutoMapper полезен сегодня и будет ли он завтра?"
По моему опыту, когда кто-то жаловался на «слишком много шаблонов» и хочет использовать AutoMapper, это было одно из следующих:
Тем не мение:
Если вы выбрали статически типизированный язык, воспользуйтесь этим языком. Если вы пытаетесь обойти средства управления на языке, которые помогают предотвратить ошибки из-за чрезмерного использования рефлексии и магических API, таких как AutoMapper, это просто означает, что вы выбрали язык, который не удовлетворяет вашим потребностям.
Кроме того, только то, что Microsoft добавила функции в C #, не означает, что они являются честной игрой в любой ситуации или что они поддерживают лучшие практики. Например, Reflection и ключевое слово «dynamic» следует использовать в тех случаях, когда вы просто не можете выполнить то, что вам нужно, без них. AutoMapper не является решением для любого случая использования, который не может быть решен без него.
Итак, является ли дублирование классов плохим дизайном? Не обязательно.
AutoMapper - плохая идея? Да, конечно.
Использование AutoMapper указывает на системные недостатки в проекте. Если вам это нужно, остановитесь и подумайте о своем дизайне. Вы всегда найдете лучший, более читаемый, более понятный и более безошибочный дизайн.
Здесь есть более глубокая проблема: тот факт, что C # и Java настаивают на том, что большинство / все типы должны различаться по имени, а не по структуре: например, class MyPoint2D
и class YourPoint2D
являются отдельными типами, даже если они имеют точно такие же определения. Когда типом, который вам нужен, является «какая-то анонимная вещь с x
полем и y
полем» (то есть с записью ), вам не повезло. Поэтому, когда вы хотите превратить YourPoint2D
в MyPoint2D
, у вас есть три варианта:
this.x = that.x; this.y = that.y
Вариант 1 достаточно прост в малых дозах, но быстро становится рутиной, когда количество типов, которые вам нужно отобразить, велико.
Вариант 2 менее желателен, потому что теперь вам нужно добавить дополнительный шаг в процесс сборки для генерации кода и убедиться, что вся команда получает памятку. В худшем случае вам придется запустить собственный генератор кода или систему шаблонов.
Это оставляет вас с отражением. Вы можете сделать это самостоятельно, или вы можете использовать AutoMapper.
Automapper - одна из тех библиотек / инструментов, где император буквально бегает голым задом. Когда вы обходите блестящий логотип, вы понимаете, что он не делает ничего, что вы не можете сделать вручную, с гораздо лучшими результатами.
Хотя я не совсем уверен, как он намекает на элементы автоматического сопоставления, он, скорее всего, требует дополнительной логики времени выполнения и возможного отражения. Это может быть значительным ухудшением производительности в обмен на экономию времени. Ручное отображение, с другой стороны, подсказка выполняется задолго до времени компиляции.
В случаях, когда AutoMapper не имеет ни малейшего представления, вы должны настроить отображение с помощью кода и установки флагов. Если вы собираетесь заняться всей работой по настройке и коду, вам придется задуматься о том, сколько это экономит по сравнению с ручным отображением.