web-dev-qa-db-fra.com

Ai-je tort de penser que le fait d'avoir besoin de quelque chose comme AutoMapper est une indication de mauvaise conception?

Automapper est un "mappeur objet-objet" pour .Net, ce qui signifie copier des objets d'une classe dans une autre classe qui représente la même chose.

Pourquoi est-ce jamais utile? La duplication des classes est-elle jamais utile/bonne conception?

36
static_rtti

Une recherche rapide sur Google a révélé cet exemple:

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

montrant une utilisation parfaitement valide d'AutoMapper qui n'est certainement pas un exemple de mauvaise conception. Dans une application en couches, vous pouvez avoir des objets dans vos données ou votre couche métier, et vous avez parfois besoin d'un sous-ensemble des attributs de ces objets de données, ou d'une sorte de vue pour eux dans votre couche d'interface utilisateur. Vous créez donc un modèle de vue qui contient des objets avec exactement les attributs dont vous avez besoin dans votre interface utilisateur, pas plus, et utilisez AutoMapper pour fournir le contenu de ces objets avec moins de code passe-partout.

Dans une telle situation, vos "objets de vue" ne sont pas un doublon de la classe d'origine. Ils ont différentes méthodes et peut-être quelques attributs en double. Mais c'est correct tant que vous n'utilisez ces objets de vue qu'à des fins d'affichage de l'interface utilisateur et ne commencez pas à les utiliser à mauvais escient pour la manipulation de données ou des opérations commerciales.

Un autre sujet que vous pouvez lire pour mieux comprendre ce sujet est le modèle Fowlers Command Query Responsibility Segregation , contrairement à CRUD. Il vous montre des situations où différents modèles d'objet pour interroger des données et les mettre à jour dans une base de données ont un sens. Ici, le mappage d'un modèle d'objet à un autre peut également être effectué par un outil comme AutoMapper.

28
Doc Brown

La duplication des classes est-elle jamais utile/bonne conception?

Il est recommandé d'avoir une classe de modèle de vue distincte à utiliser dans la couche d'interface utilisateur plutôt que d'utiliser la même classe que celle utilisée dans la couche de données. Votre interface utilisateur/page Web peut avoir besoin d'afficher d'autres bits d'informations qui ne sont pas strictement liés à l'entité de données. En créant cette classe supplémentaire, vous vous donnez la liberté de modifier facilement votre interface utilisateur à mesure que les exigences changent avec le temps.

En ce qui concerne l'utilisation d'AutoMapper, je l'évite personnellement pour 3 raisons:

Échecs silencieux plus courants

Étant donné qu'AutoMapper mappe automatiquement entre les propriétés, la modification d'un nom de propriété sur une classe et non sur l'autre entraînera l'omission du mappage de propriétés. Le compilateur ne le saura pas. Automapper s'en fiche.

Manque d'analyse statique

On vous a donc donné une grande base de code à gérer. Il y a un million de classes avec un million de propriétés. Beaucoup semblent ne pas être utilisés ou sont des doublons. Cet outil "Rechercher toutes les références" dans Visual Studio vous aidera à voir où les propriétés sont utilisées et à construire une carte dans votre tête de la façon dont l'ensemble de l'application se tient. Mais attendez, il n'y a pas de références explicites à la moitié des propriétés car Automapper est utilisé. Mon travail est maintenant beaucoup plus difficile.

Exigences tardives qui augmentent la complexité

Automapper est très bien et dandy quand tout ce que vous voulez faire est de copier les valeurs d'une classe à une autre (comme c'est souvent le cas au début du développement), mais rappelez-vous ces exigences qui changent au fil du temps? Que se passe-t-il si vous avez maintenant besoin d'obtenir des valeurs d'autres parties de votre application, peut-être spécifiques à l'utilisateur connecté ou à un autre état contextuel?

Le modèle d'AutoMapper de création des mappages de classe un-à-un au démarrage de l'application ne se prête pas bien à ce type de changements spécifiques au contexte. Oui, il y a probablement des moyens de le faire fonctionner, mais je le trouve généralement plus propre, plus simple et plus expressif pour écrire la logique moi-même.

En résumé, avant de chercher Automapper pour vous épargner 30 secondes de mappage manuel d'une classe à une autre, pensez-y.

La programmation est l'art de dire à un autre humain ce que l'on veut que l'ordinateur fasse. - Donald Knuth

Dans cet esprit, demandez-vous "AutoMapper est-il utile aujourd'hui et sera-t-il demain?"

48
Dave B 84

D'après mon expérience, lorsque quelqu'un s'est plaint de "trop de passe-partout" et souhaite utiliser AutoMapper, cela a été l'un des suivants:

  1. Ils trouvent irritant d'écrire encore et encore le même code.
  2. Ils sont paresseux et ne veulent pas écrire de code qui fait A.x = B.x.
  3. Ils sont trop pressés par le temps pour réellement penser si écrire A.x = B.x encore et encore est une bonne idée, puis écrire un bon code pour la tâche.

Toutefois:

  1. S'il s'agit vraiment d'éviter la répétition, vous pouvez créer un objet ou une méthode pour l'abstraire. Vous n'avez pas besoin d'AutoMapper.
  2. Si vous êtes paresseux, vous serez paresseux et n'apprendrez pas comment fonctionne AutoMapper. Au lieu de cela, vous adopterez le modèle de `` programmation par coïncidence '' et écrirez un code horrible où vous bourrez la logique métier dans un profil AutoMapper. Dans ce cas, vous devez changer votre attitude envers la programmation ou trouver autre chose à faire en tant que profession. Vous n'avez pas besoin d'AutoMapper.
  3. Si vous êtes trop pressé par le temps, votre problème n'a rien à voir avec la programmation elle-même. Vous n'avez pas besoin d'AutoMapper.

Si vous avez choisi une langue de type statique, profitez-en. Si vous essayez de contourner les contrôles dans le langage qui aident à éviter les erreurs dues à une utilisation excessive de la réflexion et des API magiques comme AutoMapper, cela signifie simplement que vous avez choisi un langage qui ne convient pas à vos besoins.

En outre, ce n'est pas parce que Microsoft a ajouté des fonctionnalités à C # qu'ils sont équitables dans toutes les situations ou qu'ils prennent en charge les meilleures pratiques. La réflexion et le mot-clé "dynamique", par exemple, devraient être utilisés dans les cas où vous ne pouvez tout simplement pas accomplir ce dont vous avez besoin sans eux. AutoMapper n'est pas une solution pour tout cas d'utilisation qui ne peut pas déjà être résolu sans lui.

Alors, la duplication des classes est-elle une mauvaise conception? Pas nécessairement.

AutoMapper est-il une mauvaise idée? Oui absolument.

L'utilisation d'AutoMapper indique des lacunes systémiques dans le projet. Si vous en avez besoin, arrêtez-vous et pensez à votre conception. Vous trouverez toujours une conception meilleure, plus lisible, plus facile à entretenir et sans bogues.

22

Il y a un problème plus profond ici: le fait que C # et Java insistent sur le fait que la plupart/tous les types doivent être distinguables par leur nom plutôt que par leur structure: par exemple class MyPoint2D et class YourPoint2D sont des types distincts même s'ils ont exactement les mêmes définitions. Lorsque le type que vous voulez est "une chose anonyme avec un champ x et un champ y" (c'est-à-dire un enregistrement), vous n'avez pas de chance. Donc, quand vous voulez transformer un YourPoint2D dans une MyPoint2D, vous avez trois options:

  1. Écrivez un passe-partout fastidieux, répétitif et banal sur le modèle de this.x = that.x; this.y = that.y
  2. Générez le code d'une manière ou d'une autre.
  3. Utilisez la réflexion.

Le choix 1 est assez facile à petites doses mais devient rapidement une corvée lorsque le nombre de types à cartographier est important.

Le choix 2 n'est pas souhaitable, car vous devez maintenant ajouter une étape supplémentaire à votre processus de génération pour générer le code et vous assurer que toute l'équipe reçoit le mémo. Dans le pire des cas, vous devez également utiliser votre propre générateur de code ou système de modèles.

Cela vous laisse avec réflexion. Vous pouvez le faire vous-même ou utiliser AutoMapper.

7
Doval

Automapper est l'une de ces bibliothèques/outils où l'empereur court littéralement bout à bout. Lorsque vous dépassez le logo fastueux, vous vous rendez compte qu'il ne fait rien que vous ne pouvez pas faire manuellement avec de bien meilleurs résultats.

Bien que je ne sois pas entièrement sûr de la façon dont il suggère les membres de mappage automatique, cela implique très probablement une logique d'exécution supplémentaire et une réflexion possible. Cela peut être une pénalité de performance importante en échange d'un gain de temps. Le mappage manuel, en revanche, l'indication est exécutée bien avant la compilation.

Dans les cas où AutoMapper n'a aucun indice, vous devez configurer le mappage avec du code et définir des indicateurs. Si vous allez prendre la peine de faire tout le travail de configuration et de code, vous devez vous demander combien il économise par rapport au mappage manuel.

4
user148298