1

私は以下のクラスを持っています:

  クラスバリデーター{
    プライベート最終SchemaFetcher schemaFetcher;

    @注入
    Validator(SchemaFetcher schemaFetcher) {...}
  }

  クラス DatabaseSchemaFetcher は SchemaFetcher を実装します {
     @オーバーライド
     スキーマ loadSchema(最終的な SchemaDefinition schemaDef);

     @オーバーライド
     boolean compareSchemaWithSource(最終的な SchemaDefinition schemaDef、最終的なスキーマ updatedSchema);
  }

これは例の 1 つにすぎません。依存関係として他のクラスに注入する、このような他のクラスがいくつかあります。しかし、それは私の SchemaFetcher クラスをシングルトンのようにし、そのすべてのメソッドに schemaDefinition を渡し続けます。これは非常に手続き的なようで、実際に SchemaDefinition を DatabaseSchemaFetcher クラスのインスタンス変数にしたいのですが、その場合、SchemaFetcher オブジェクトを Validator クラスに挿入できず、代わりに行う必要があります

   検証(文字列スキーマ名){
     SchemaDefinition schemaDef = buildSchemaDefinitionFrom(schemaName);
     SchemaFetcher fetcher = 新しい DatabaseSchemaFetcher(schemaDef);
   }

しかし、これにより、フェッチャーと密接に結びついてしまうため、最初に依存性注入を使用したいと考えました。

DatabaseSchemaFetcher のデフォルトのコンストラクターと setSchemaDefintion() セッターを使用してこれを実現できる可能性があることがわかりますが、それはコンストラクターを使用してオブジェクトを完全に構築するという原則に違反しています。

これを改善して、手続き型のフェッチャーを持たないようにするだけでなく、依存関係をコンストラクターに注入するにはどうすればよいですか? ファクトリーまたはサービスロケーターを使用する場合、誰もクラスの実装を調べてクラスが使用する依存関係を把握することなく、依存関係を明確に定義するため、コンストラクター注入を好みます。

4

3 に答える 3

5

依存性注入は、非常に優れていると思われる非常に優れたアイデアの1つであり、ひどく使いすぎになります。DIフレームワークを使用してFetcherをバリデーターに注入しません。むしろ、DIフレームワークにファクトリを「メイン」に注入させます。ファクトリは、適切なSchemaDefinitionを使用してFetcherを作成し、それをValidatorに渡します。

「メイン」をアプリケーションの残りの部分から分離する境界が必要であり、すべての依存関係が「メイン」からアプリケーションを指す必要があることに注意してください。アプリケーションは「メイン」について知らないはずです。つまり、「メイン」はアプリケーションへのプラグインです。

一般に、DIを使用して「メイン」に注入し、メインはより従来の手法を使用して、ファクトリ、戦略、または通常の古い抽象インターフェイスをアプリケーションに渡します。

于 2012-07-01T18:24:21.093 に答える
0

2 番目のソリューションで SchemaFetcher と密接に結合していると言うのはなぜですか?
そこにインターフェイスを提供しているため、特定の実装には結合されていませんが、SchemaFetcher が何であるかの定義 (つまり、SchemaFetcher の契約) にのみ結合されています
。 SchemaDefinition、および DatabaseSchemaFetcher はそれにフィールドを保持できます。このようにして、Validator クラスを拡張して、必要に応じて検証ロジックを変更することもできます。
しかし、スキーマ定義オブジェクトをどのように渡すかという問題が再び発生します。ここでインジェクションを使用する必要があるかどうかわからない - 設計を変更することを検討してください。

于 2012-07-01T16:43:09.460 に答える
0

この場合、何を使用し、互いに何をしなければならDependecy Injectionないのか正確にはわかりません。Procedural

本当の問題は、オブジェクトをモデル化するために選択した方法が、指定された目標を反映していないことだと思います。

あなたが提供したコードではValidator、私が見ることができる目的はありません。その目的がオブジェクトを検証することである場合、おそらく検証のルールを超えた状態を持たず、検証する任意のオブジェクトをSchemaFetcher受け入れる必要があります。SchemaFetcher

DataBaseSchemaFetcher私はもう一度、これが何をするのか理解するのに苦労しています。宣言された目的がスキーマのフェッチのみである場合、DatabaseSchemaオブジェクトに関する状態は不要DatabaseSchemaであり、DatabaseSchema. 内部状態は、クラスのフェッチ動作にのみ関連する必要があります。

これらのpainted in a corner状況を乗り越えるための実証済みの確実な方法の 1 つは、座って各クラスに 1 つの責任を割り当て、次の点に留意することです。

  1. あなたが解決しようとしている正確な問題のドメインについて本当に難しいこと。

  2. 持っていない問題は解決しないでください。拡張性の夢を捨てて捨ててください。それらはほとんど常に間違っており、膨大な時間を浪費するだけです。

  3. あなたのデザインには必然的に欠陥があり、後で変更する必要があることを受け入れてください。

于 2012-07-01T18:40:51.660 に答える