AutoMapperのようなものが必要なのは、デザインの悪さを示していると考えるのは間違っていますか?


35

Automapperは.Netの「オブジェクト-オブジェクトマッパー」です。つまり、オブジェクトをクラスから同じものを表す別のクラスにコピーします。

なぜこれが便利なのですか?クラスの複製はこれまでに役立つ/良いデザインですか?


ちょっとした参考文献:devtrends.co.uk/blog / ...特に「オートマッパーを使用できない理由」セクションを読んでください。
ジャニHyytiäinen14年

回答:


28

簡単なグーグル検索でこの例を明らかにしました:

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

AutoMapperの完全に有効な使用法を示していますが、これはデザインが悪い場合の例ではありません。レイヤー化されたアプリケーションでは、データまたはビジネスレイヤーにオブジェクトがある場合があり、そのデータオブジェクトの属性のサブセット、またはUIレイヤーでそれらに対する何らかのビューが必要な場合があります。そのため、UIに必要な属性だけを持つオブジェクトを含むビューモデルを作成し、AutoMapperを使用して、より少ない定型コードでそのオブジェクトのコンテンツを提供します。

このような状況では、「ビューオブジェクト」は元のクラスの複製ではありません。それらには異なる方法があり、おそらくいくつかの重複する属性があります。ただし、UIを表示する目的でのみそのビューオブジェクトを使用し、データ操作やビジネスオペレーションに悪用し始めない限り、これは問題ありません。

これをよりよく理解するために読むことができる別のトピックは、CRUDとは対照的に、ファウラーのコマンドクエリの責任分離パターンです。データを照会してデータベースで更新するためのさまざまなオブジェクトモデルが意味をなす状況を示しています。ここで、あるオブジェクトモデルから別のオブジェクトモデルへのマッピングは、AutoMapperなどのツールによって実行することもできます。


1
最初の例について:オブジェクトを複製するのではなく作成できませんでしたか?その場合、UIオブジェクトは元のデータオブジェクトへの参照を持ち、必要な要素のみを公開します。それは理にかなっていないでしょうか?
-static_rtti

1
理論的には@static_rttiはい、ただし、元のクラスを公開したり、アセンブリで公開したりする必要は必ずしもないかもしれません
-Jalayn

2
@static_rtti:はい、それは完全に有効な異なるアプローチです。これらの2つの設計の主な違いは、データ/属性の寿命です。コピーを使用すると、データのスナップショットが提供されますが、元のデータを参照するプロパティを使用しても提供されません。どちらのアプローチにも長所と短所がありますが、IMHOには一般に「より良い」または「悪い」はありません。さらに、パフォーマンスの考慮事項が存在する場合がありますが、これは何を使用するかの決定に影響する場合と影響しない場合があります。
ドックブラウン

3
可能な限りデカップリングすることは常に良い考えです。小さなプロジェクトでも特に有益だからではなく、プロジェクトが成長するからです。
タマスシェレイ

6
@fish:たいていは同意しますが、デカップリングはしばしば良いアイデアですが、私見では、物事をシンプルに保つことは、デカップリングのための多層スーパーデカップリングアプローチよりも十分な状況があります。難しいのは、プロジェクトの成長中にリファクタリングを開始すべきポイントを見逃さないことです。
ドックブラウン

45

クラスの複製はこれまでに役立つ/良いデザインですか?

データレイヤーで使用されているのと同じクラスを使用するのではなく、UIレイヤーで使用する別のビューモデルクラスを持つことをお勧めします。UI / Webページには、データエンティティに厳密に関連していない他の情報を表示する必要がある場合があります。この追加のクラスを作成することで、要件が時間の経過とともに変化するときにUIを簡単に微調整できるようになります。

AutoMapperの使用に関しては、次の3つの理由で個人的に回避しています。

より一般的なサイレント障害

AutoMapperはプロパティ間を自動的にマッピングするため、あるクラスのプロパティ名を変更し、他のクラスを変更しないと、プロパティマッピングがスキップされます。コンパイラーは知りません。Automapperは気にしません。

静的解析の欠如

そのため、対処するための大きなコードベースが与えられました。100万のプロパティを持つ100万のクラスがあります。使用されていないか、重複しているように見えます。Visual Studioの「すべての参照を検索」ツールを使用すると、プロパティが使用されている場所を確認し、アプリケーション全体がどのように連携するかのマップを構築できます。ただし、Automapperが使用されているため、プロパティの半分への明示的な参照はありません。私の仕事は今ではかなり大変です。

複雑さを増す後期要件

Automapperは、1つのクラスから別のクラスに値をコピーするだけの場合(開発の開始時によくあることです)、時間の経過とともに変化する要件を覚えていますか?アプリケーションの他の部分から値を取得する必要が生じた場合、おそらくログインしているユーザーや他のコンテキスト状態に固有のものでしょうか?

アプリケーションの起動時に1対1のクラスマッピングを作成するAutoMapperのパターンは、こうした種類のコンテキスト固有の変更には適していません。はい、おそらくそれを機能させる方法がありますが、私は通常、自分でロジックを書く方がより簡潔でシンプルで表現力豊かだと感じています。

要約すると、Automapperが1つのクラスを別のクラスに手動でマッピングする時間を30秒節約する前に、これについて考えてください。

プログラミングとは、コンピューターに何をしてほしいかを他の人間に伝える技術です。-ドナルド・クヌース

これを念頭に置いて、「今日AutoMapperは役に立ちますか、明日は役に立ちますか」と自問してください。


[トレンディなWeb開発を行う場合]では、REST Webサービスを作成する場合、JavaScriptオブジェクトモデルが.NETオブジェクトモデルと一貫性があることを確認するために、常にすべてのプロパティをチェックする傾向がありますか?
デン14

3
@Den-はい。そして、すべてのプロパティが正しいことを確認するテストを作成します(つまり、他の層に伝播されない1か所で追加したプロパティがテストに表示されます)
gbjbaanb 14

@gbjbaanbおそらくリフレクションを使用して、一般的な方法でこの検証を行うでしょう。おそらく、AutoMapperを拡張して検証を追加する可能性を検討してください。手動での割り当ての多くは間違いなく避けられます
デン

完全に同意し、非常にシンプルなアプリのみがオートマッパーを使用できると考えますが、事態が複雑になる場合は、オートマッパーの新しい構成を作成する必要があります。手動マッパーヘルパーまたはサービスでそれらを作成してください。
ahmedsafan86

21

私の経験では、誰かが「ボイラープレートが多すぎる」と不平を言ってAutoMapperを使用したい場合、それは次のいずれかです。

  1. 同じコードを何度も書くのはいらいらします。
  2. 彼らは怠け者で、Ax = Bxを実行するコードを書きたくない
  3. 彼らは、Ax = Bxを何度も書くのが良い考えであるかどうかを実際に考え、そのタスクに適したコードを書くには、あまりにも時間的なプレッシャーにさらされています。

しかしながら:

  1. 繰り返しを回避することが本当に目的であれば、オブジェクトまたはメソッドを作成して抽象化することができます。AutoMapperは必要ありません。
  2. あなたが怠け者なら、あなたは怠け者になり、AutoMapperがどのように機能するかを学びません。代わりに、「偶然のプログラミング」パターンを採用し、AutoMapperプロファイルにビジネスロジックを詰め込む恐ろしいコードを記述します。この場合、プログラミングに対する態度を変えるか、職業として他に何かをする必要があります。AutoMapperは必要ありません。
  3. 時間のプレッシャーが大きすぎる場合、問題はプログラミング自体とは関係ありません。AutoMapperは必要ありません。

静的に型付けされた言語を選択した場合は、その言語を活用してください。リフレクションとAutoMapperのような魔法のAPIの過剰使用に起因するミスを防ぐのに役立つ言語のコントロールを回避しようとする場合、それは単に、ニーズに合わない言語を選択したことを意味します。

また、MicrosoftがC#に機能を追加したからといって、すべての状況で公正なゲームであることや、ベストプラクティスをサポートしていることを意味しません。たとえば、リフレクションと「動的」キーワードは、それなしでは必要なことを達成できない場合に使用する必要があります。AutoMapperは、それなしでは解決できないユースケースのソリューションではありません。

それで、クラスの複製は悪い設計ですか?必ずしも。

AutoMapperは悪い考えですか?そのとおり。

AutoMapperの使用は、プロジェクトの体系的な欠陥を示しています。必要な場合は、設計をやめて考えてください。常に、より良く、より読みやすく、より保守しやすく、バグのないデザインを見つけるでしょう。


1
特に、2を言いました。
Mardoxx

2
私はこれが非常に古いスレッドであることを知っていますが、1に同意する必要があります。マッピングを抽象化するメソッドを作成することはできません。1つのクラスに対応できますが、2つのクラスがある場合は2つのメソッドが必要です。3-3つの方法。AMでは、これは1行のコード-マッピングの定義です。さらに、10個のサブタイプDTOで満たされたList <BaseType>があるシナリオに本当に苦労しました。それをマップしたいときは、フィールドの値をコピーするためのタイプとメソッドのスイッチが必要です。また、フィールドの1つを個別にマッピングする必要がある場合はどうなりますか?単純なクラスがほとんどない場合にのみ、答えは適切です。AutoMapperは、より複雑なシナリオで勝ち抜きます。
user3512524

1
(charの制限)AMの唯一の落とし穴は、あるクラスのプロパティ名を変更し、他のクラスのプロパティ名を変更できないことです。しかし、実際には、設計が完了した後、どのくらいの頻度でそれを行いますか?また、リフレクションを使用してプロパティ名を比較する一般的なテストメソッドを作成できます。すべてのツールと同様に、AMは正しく使用する必要があります-盲目的ではなく、すべての状況でそうではありません。しかし、「あなたはそれを使うべきではない」と言うのは間違っています。
user3512524

7

ここでのより深い問題があります:例えば:C#とJavaは、すべてのタイプの名前ではなく、構造によって区別でなければならない/ほとんどを主張しているという事実class MyPoint2Dclass YourPoint2D、彼らはまったく同じ定義を持っている場合でも、別のタイプのですが。必要なタイプが「xフィールドとフィールドを持つ匿名のものy」(つまりレコード)である場合、あなたは運が悪いです。したがって、をにYourPoint2D変換するMyPoint2D場合、次の3つのオプションがあります。

  1. 退屈で繰り返しのありふれた定型文を、 this.x = that.x; this.y = that.y
  2. なんとかしてコードを生成します。
  3. リフレクションを使用します。

選択肢1は少量でも十分簡単ですが、マッピングする必要があるタイプの数が多い場合はすぐに面倒になります。

選択肢2は、コードを生成するためにビルドプロセスに追加のステップを追加し、チーム全体がメモを取得するようにする必要があるため、あまり望ましくありません。最悪の場合、独自のコードジェネレーターまたはテンプレートシステムもロールする必要があります。

それはあなたに反射を残します。あなたはそれを自分でやるか、AutoMapperを使うことができます。


3

Automapperは、皇帝が文字通り裸で走り回っているライブラリ/ツールの1つです。派手なロゴをすり抜けると、手作業ではできないことを実行しても、より良い結果が得られることがわかります。

メンバーの自動マッピングをどのように示唆しているかは完全にはわかりませんが、ほとんどの場合、追加のランタイムロジックと考えられるリフレクションが含まれます。これは、時間の節約と引き換えに重大なパフォーマンスの低下になる可能性があります。一方、手動マッピングは、コンパイル時間のかなり前にヒントを実行します。

AutoMapperにヒントがない場合は、コードを使用してマッピングを設定し、フラグを設定する必要があります。すべてのセットアップとコード作業をわざわざ行うつもりなら、手動マッピングに比べてどれだけ節約できるかを疑問視する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.