web-dev-qa-db-ja.com

AutoMapperのようなものが必要であるとは、デザインが悪いことを示していると私が思うのは間違っていますか

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

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

36
static_rtti

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

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

autoMapperの完全に有効な使用法を示していますが、これは間違いなく貧弱な設計の例ではありません。レイヤードアプリケーションでは、データレイヤーまたはビジネスレイヤーにオブジェクトがあり、そのデータオブジェクトの属性のサブセット、またはUIレイヤーでそれらに対する何らかのビューが必要な場合があります。したがって、UIで必要な属性だけを備えたオブジェクトを含むビューモデルを作成し、AutoMapperを使用して、ボイラープレートコードを減らしてそのオブジェクトのコンテンツを提供します。

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

これをよりよく理解するために読むことができるもう1つのトピックは、CRUDとは対照的に、Fowlers Command Query Responsibility Segregation パターンです。これは、データをクエリしてデータベースで更新するためのさまざまなオブジェクトモデルが理にかなっている状況を示しています。ここで、1つのオブジェクトモデルから別のオブジェクトモデルへのマッピングは、AutoMapperなどのツールでも実行できます。

28
Doc Brown

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

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

AutoMapperの使用に関する限り、私は個人的には3つの理由でそれを避けています。

サイレント障害の方が一般的

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

静的分析の欠如

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

複雑さを増す最近の要件

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

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

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

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

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

48
Dave B 84

私の経験では、誰かが「定型文が多すぎる」と不満を示し、AutoMapperを使用したい場合、それは次のいずれかでした。

  1. 彼らは同じコードを何度も書くのはイライラします。
  2. 彼らは怠惰で、A.x = B.xを実行するコードを記述したくありません。
  3. 彼らは、A.x = B.xを何度も書くことが良いアイデアであるかどうかを実際に考えてから、タスクの適切なコードを書くために、あまりにも多くの時間的プレッシャーにさらされています。

しかしながら:

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

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

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

では、クラスの複製は悪いデザインですか?必ずしも。

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

AutoMapperの使用は、プロジェクトの体系的な欠陥を示します。あなたがそれを必要としていることに気づいたら、立ち止まってあなたのデザインについて考えてください。あなたはいつもより良く、より読みやすく、より保守可能で、よりバグのないデザインを見つけるでしょう。

22

ここにはさらに深い問題があります。C#とJavaは、ほとんどの/すべての型は構造ではなく名前で識別できる必要があると主張しています。たとえば、class MyPoint2Dclass YourPoint2Dは別々ですタイプがまったく同じ定義であってもタイプします。必要なタイプが「xフィールドとyフィールドを持つ匿名のもの」(つまりrecordの場合) )、あなたは運が悪いので、YourPoint2DMyPoint2Dに変換したい場合、3つのオプションがあります。

  1. this.x = that.x; this.y = that.yに沿って、退屈で繰り返しの多い、ありふれた定型文を書きます。
  2. どういうわけかコードを生成します。
  3. リフレクションを使用します。

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

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

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

7
Doval

Automapperは、皇帝がお尻の周りを文字通り裸で走っているライブラリ/ツールの1つです。派手なロゴを通り過ぎると、手動ではできないことは何もしないことに気づき、より良い結果が得られます。

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

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

4
user148298