Я помиляюся, думаючи, що потрібне щось на кшталт AutoMapper - це ознака поганого дизайну?


35

Automapper - це "об'єкт-об'єктний картограф" для .Net, що означає копіювання об'єктів з класу в інший клас, який представляє те саме.

Чому це завжди корисно? Чи дублювання класів завжди корисне / хороший дизайн?


Невелика довідка: devtrends.co.uk/blog/… Особливо прочитайте розділ "чому ми не можемо використовувати автоматизатор?"
Jani Hyytiäinen

Відповіді:


28

Швидкий пошук Google виявив такий приклад:

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

показуючи ідеально правильне використання AutoMapper, що, безумовно, не є прикладом для поганого дизайну. У шаруватій програмі у вас можуть бути об'єкти у вашому шарі даних або бізнес, і вам іноді потрібна лише підмножина атрибутів цих об’єктів даних або певний вид на них у вашому шарі інтерфейсу користувача. Таким чином, ви створюєте модель представлення, яка містить об'єкти з точно атрибутами, які вам потрібні у вашому інтерфейсі, а не більше, і використовуєте AutoMapper для надання вмісту цих об'єктів з меншим кодом котла.

У такій ситуації ваші "об'єкти перегляду" не є дублікатом оригінального класу. Вони мають різні методи і, можливо, кілька повторюваних атрибутів. Але це нормально, якщо ви використовуєте ці об'єкти перегляду лише для відображення інтерфейсу користувача та не почнете використовувати їх для маніпулювання даними або для ділових операцій.

Ще одна тема, яку ви можете прочитати, щоб краще зрозуміти це, - це схема розбиття відповідальності за запити Fowlers на відміну від CRUD. Він показує вам ситуації, коли різні об'єктні моделі для запиту даних та оновлення їх у базі даних мають сенс. Тут відображення від однієї об'єктної моделі до іншої також може бути здійснено за допомогою інструменту типу AutoMapper.


1
Щодо вашого першого прикладу: чи не могли ви складати об'єкти, а не дублювати їх? У такому випадку ваші об’єкти інтерфейсу можуть мати посилання на ваші оригінальні об'єкти даних і викриватимуть лише необхідні елементи. Хіба це не має сенсу?
static_rtti

1
@static_rtti теоретично так, але ви не обов'язково хочете, щоб ваш початковий клас був публічним або / і був виставлений на зборах
Jalayn

2
@static_rtti: так, це ідеально правильний, різний підхід. Основна відмінність цих двох конструкцій - це термін служби даних / атрибутів. Використання копій надає вам знімок даних, використання властивостей, що посилаються на вихідні дані, не робить. Обидва підходи мають свої плюси і мінуси, але в ІМХО взагалі немає "кращого або гіршого". Крім того, можуть існувати міркування щодо ефективності роботи, які можуть впливати на рішення щодо використання.
Док Браун

3
Максимальна розв'язка - це завжди хороша ідея. Не тому, що це особливо вигідно навіть для невеликих проектів, а тому, що проекти ростуть.
Tamás Szelei

6
@fish: В основному, я згоден, розв'язка часто є хорошою ідеєю, але в IMHO є достатньо ситуацій, коли зберігання речей переважає над підходом багатошарового супер-декупажу-заради-розв’язки. Важкою частиною є не пропустити крапку під час зростання проекту, коли слід почати рефакторинг.
Док Браун

45

Чи дублювання класів завжди корисне / хороший дизайн?

Його найкраща практика мати окремий клас моделі перегляду для використання в шарі інтерфейсу, а не використовувати той самий клас, який використовується в рівні даних. У вашому інтерфейсі / веб-сторінці може знадобитися відображення інших бітів інформації, які не суворо пов'язані з сукупністю даних. Створюючи цей додатковий клас, ви даєте собі свободу легко налаштувати інтерфейс користувача, оскільки вимоги з часом змінюються.

Що стосується використання AutoMapper, я особисто уникаю цього з 3 причин:

Мовчазні збої частіше зустрічаються

Оскільки AutoMapper автоматично відображає між властивостями, зміна назви властивості для одного класу, а не іншого, призведе до того, що відображення властивостей буде пропущено. Компілятор не знатиме. Automapper не хвилює.

Відсутність статичного аналізу

Тож вам дали велику базу коду для вирішення. Є мільйон класів з мільйоном властивостей. Багато виглядають, як вони не використовуються, або є дублікатами. Цей інструмент «Знайти всі посилання» у Visual Studio допоможе вам побачити, де використовуються властивості, і допоможе побудувати карту в голові про те, як уся програма зависає. Але зачекайте, явних посилань на половину властивостей немає, оскільки використовується Automapper. Моя робота зараз пекло набагато важче.

Пізні вимоги, що збільшують складність

У Automapper все гаразд і денді, коли все, що ви хочете зробити, - це скопіювати значення з класу ONE в інший (як це часто буває на START розвитку), але пам’ятаєте ті вимоги, які змінюються з часом? Що робити, якщо вам зараз потрібно отримати значення з інших частин вашої програми, можливо, специфічних для користувача, який увійшов у систему, або якогось іншого контекстуального стану?

Схема створення AutoMapper створення індивідуальних відображень класу під час запуску програми не піддається таким видам змін, що стосуються конкретного контексту. Так, напевно, є способи змусити його працювати, але я зазвичай вважаю більш чистим, простішим та виразним, щоб писати логіку сам.

Підводячи підсумок, перш ніж звернутися до Automapper, щоб заощадити 30 секунд вручну зіставлення одного класу в інший, подумайте про це.

Програмування - це мистецтво розповісти іншій людині, що хоче робити комп’ютер. - Дональд Кнут

Зважаючи на це, запитайте себе: "Чи корисний AutoMapper сьогодні і чи буде він завтра?"


[якщо ви робите модний веб-розробник] Отже, якщо ви пишете веб-службу REST, чи схильні ви завжди перевіряти кожну власність, щоб переконатися, що ваша об’єктна модель JavaScript відповідає вашій .NET-об'єктній моделі?
День

3
@Den - так. І ви пишете тести, щоб переконатися, що всі властивості правильно (тобто ваш тест покаже будь-які властивості, які ви додали в 1 місці, які не поширюються на інші яруси)
gbjbaanb

@gbjbaanb Я, мабуть, просто використав роздуми, щоб зробити цю перевірку загальним способом. Можливо, вивчіть можливість розширення AutoMapper, щоб додати деяку перевірку. Однозначно уникне безліч ручних завдань.
День

Цілком погоджуюся з вами, і думаю, що лише дуже прості програми можуть використовувати автомати, але коли все стає складнішим, нам потрібно написати нову конфігурацію для автоматичної програми, а чому б не записати їх у помічник або сервіс вручну.
ahmedsafan86

21

З мого досвіду, коли хтось скаржився на "занадто багато котла" і хоче використовувати AutoMapper, це було одним із наступних дій:

  1. Вони вважають дратівливим писати один і той же код знову і знову.
  2. Вони ліниві і не хочуть писати код, який робить Ax = Bx
  3. Вони знаходяться під занадто великим тиском часу, щоб насправді задуматися над тим, чи правильно писати Ax = Bx, а потім написати хороший код для завдання.

Однак:

  1. Якщо мова йде справді про те, щоб уникнути повторення, ви можете створити об’єкт або метод, щоб його абстрагувати. Вам не потрібен AutoMapper.
  2. Якщо ти лінивий, ти будеш лінивим і не дізнаєшся, як працює AutoMapper. Натомість ви приймете схему "програмування за збігом обставин" і напишете жахливий код, де ви вписуєте бізнес-логіку в профіль AutoMapper. У цьому випадку слід змінити своє ставлення до програмування або знайти щось інше, як займатися професією. Вам не потрібен AutoMapper.
  3. Якщо у вас занадто великий часовий тиск, ваша проблема не має нічого спільного з самим програмуванням. Вам не потрібен AutoMapper.

Якщо ви вибрали статичну мову, скористайтеся цією мовою. Якщо ви намагаєтеся обійти елементи управління мовою, які допомагають запобігти помилкам через надмірне використання API відображення та магії, як-от AutoMapper, це просто означає, що ви вибрали мову, незадовільну для ваших потреб.

Крім того, тільки те, що Microsoft додав функції до C #, не означає, що вони є чесною грою у будь-якій ситуації або що вони підтримують кращі практики. Наприклад, відображення та "динамічне" ключове слово слід застосовувати у випадках, коли без них просто неможливо виконати те, що потрібно. AutoMapper не є рішенням для будь-якого випадку використання, який вже не може бути вирішений без нього.

Отже, чи є дублювання класів поганим дизайном? Не обов'язково.

Чи AutoMapper погана ідея? Так, абсолютно.

Використання AutoMapper вказує на системні недоліки в проекті. Якщо ви виявите, що вам це потрібно, зупиніться і подумайте над своїм дизайном. Ви завжди знайдете вдосконалений, більш читабельний, більш ремонтований та без помилок дизайн.


1
Добре сказано, зокрема 2.
Мардокс

2
Я знаю, що це дуже стара нитка, але я повинен не погодитися з 1. Ви не можете зробити метод абстрактного відображення. Можна для 1 класу, але якщо є 2, то потрібно 2 методи. 3 - 3 методи. З AM це 1 рядок коду - визначення відображення. Крім того, я дійсно боровся зі сценарієм, коли у мене був Список <BaseType>, наповнений 10 підтипами DTO. Коли ви хочете відобразити це, вам потрібен перемикач на тип І метод для копіювання значень поля. А що робити, якщо одне з полів потрібно окремо відобразити? Ваша відповідь хороша, лише якщо у вас є кілька простих занять. AutoMapper виграє руки в більш складних сценаріях.
користувач3512524

1
(char limit) Єдиним недоліком AM, на який я думаю, є можливість зміни назви майна в одному класі, а не в іншому. Але насправді, як часто ви робите це після того, як зроблено дизайн? І ви можете написати загальний метод тестування, який використовує відображення та порівнює назви властивостей. Як і всі інструменти, AM потрібно використовувати правильно - не наосліп, не у всіх ситуаціях, я згоден. Але сказати «не слід цим користуватися» - просто неправильно.
користувач3512524

7

Існує більш глибока проблема: справа в тому , що C # і Ja наполягають більшість / всі типи повинні бути помітні на ім'я , а не структури: наприклад , class MyPoint2Dі class YourPoint2Dокремі види , навіть якщо вони мають точно таке ж визначення. Коли потрібний тип - «якась анонімна річ із xполем і yполем» (тобто запис ), вам не пощастило. Отже, коли ви хочете перетворити YourPoint2Dна "a" MyPoint2D, у вас є три варіанти:

  1. Напишіть кілька нудних, повторюваних, мирських котлів за рядками this.x = that.x; this.y = that.y
  2. Створити код якось.
  3. Використовуйте рефлексію.

Вибір 1 досить легкий у малих дозах, але швидко стає справжньою справою, коли кількість типів, які потрібно зіставити, велике.

Вибір 2 є менш ніж бажаним, оскільки тепер вам потрібно додати додатковий крок до процесу збирання, щоб створити код, і переконатися, що вся команда отримає нагадування. У гіршому випадку вам також доведеться закатати власний генератор коду чи систему шаблонів.

Це залишає у вас роздуми. Ви можете зробити це самостійно, або ви можете використовувати AutoMapper.


3

Automapper - одна з тих бібліотек / інструментів, де імператор буквально бігає по задній голі. Коли ви проходите повз блискучого логотипу, ви розумієте, що він не робить нічого, чого ви не можете зробити вручну з набагато кращими результатами.

Хоча я не зовсім впевнений, як це натякає на членів автоматичного картографування, це, швидше за все, передбачає додаткову логіку виконання та можливе відображення. Це може бути значною ефективністю покарання в обмін на економію часу. З іншого боку, підказки вручну виконуються задовго до моменту компіляції.

У випадках, коли AutoMapper не має поняття, потрібно налаштувати відображення за допомогою коду та встановлення прапорів. Якщо ви збираєтеся заважати виконувати всі налаштування та роботи з кодом, вам доведеться сумніватися, скільки це економить на ручному картографуванні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.