DI / IoCコンテナーを既存のアプリケーションに統合する際の推奨事項


10

私は現在、制御の反転(IoC)コンテナーを既存のアプリケーションに統合することに直面しており、カップリングを減らし、それによってテスト容易性を高めるという最終的な目標でそれを最も簡単に達成できる方法に関するいくつかの推奨事項を探しています。私は通常、ほとんどのクラスを神のオブジェクトとして分類しませんが、静的、シングルトン、およびインターフェイスの欠如により、それぞれに責任が多すぎ、依存関係が隠されています。

以下は、直面する必要があるいくつかの課題の背景です。

  • 依存性注入はほとんど使用されません
  • 静的メソッドが豊富-ファクトリーメソッドとヘルパーメソッドの両方として
  • シングルトンはかなり普及しています
  • インターフェースを使用すると、きめ細かすぎない
  • オブジェクトは多くの場合、基本クラスを通じて不要な依存関係を取り込みます

私たちの意図は、次に特定の領域で変更を加える必要があるときに、実際には存在するが、シングルトンやスタティックなどのグローバルの背後に隠されている依存関係を取り除くことを試みることです。

IoCコンテナが依存性注入の導入の副次的な要素になると思いますが、これらの依存関係を打開するのに役立つ、実行または推奨できる一連のプラクティスと推奨事項があると思います。


3
私はこれを今行う理由を尋ねる必要があります...この変化を引き起こしているものは何ですか?メンテナンス性?それは指数関数的に成長するので、スケーラビリティ?開発者は退屈ですか?
アーロンマクイバー、2011年

1
私は最近入社し、いくつかの「ベストプラクティス」を紹介しようとしています。私の主な目標は、テスト容易性を高め、結合を減らすことです。新しいコードにDI / IoCを簡単に使用でき、既存のすべてのコードを一度に変更しようとするつもりはありませんが、次に作成するときに既存のコードをより良く変更できるようにするための推奨事項を教えてくださいその地域の変化。これまでのところ、私がオンラインで見つけた唯一のものは次のとおりです。code.google.com
Kaleb Pederson

3
多数の自動ユニット/統合テストが実施されていない限り、ベストプラクティスのために問題が存在しない限り、既存のインフラストラクチャを変更すると、問題が発生します。あなたのユニット/統合テストスイートがしっかりしていたとしても、私はまだためらっていました。
アーロンマクイバー、2011年

1
@Aaronベストプラクティスのためにやっているように聞こえなかったことを願っています。特定の領域で作業しているため、既存のコードで作業することは困難で遅いため、変更を加えています。嬉しいことに、変更をサポートするための一連の合理的な統合テストといくつかの単体テストがあります。
Kaleb Pederson、2011年

回答:


8

このようなものを引き出すためには、段階的に作業する必要があります。これらのそれぞれは簡単ではありませんが、達成することができます。始める前に、このプロセスを急ぐことができないことを理解する必要があります。

  1. アプリケーションの主要なサブシステムとinterfaceそれぞれのサブシステムを定義します。このインターフェースは、システムの他の部分がそれと通信するために使用するメソッドのみを定義する必要があります。注:これで複数のパスを取る必要がある場合があります。
  2. 既存のコードに委任するインターフェースのラッパー実装を提供します。この演習の目的は、一括での書き換えを回避することですが、新しいインターフェイスを使用するようにコードをリファクタリングすることです。つまり、システムのカップリングを減らします。
  3. IoCコンテナーをセットアップして、作成したインターフェースと実装を使用してシステムを構築します。この段階で、IoCコンテナをインスタンス化してアプリケーションを起動できるようにします。つまり、サーブレット環境にいる場合は、サーブレットinit()メソッドでコンテナを取得/作成できることを確認してください。
  4. 各サブシステム内で同じことをもう一度行います。今回はリファクタリングするときに、スタブ実装を実際のものに変え、次に、インターフェースを使用してコンポーネントと通信します。
  5. コンポーネントのサイズと機能のバランスが適切になるまで、必要に応じて繰り返します。

完了したら、システムに必要な唯一の静的メソッドは、真に関数であるものです。たとえば、Collectionsクラスやクラスを調べますMath。静的メソッドが他のコンポーネントに直接アクセスしようとするべきではありません。

これはかなりの時間がかかるものです。それに応じて計画してください。リファクタリングを実行すると、設計アプローチがより確実になります。最初は苦痛でしょう。アプリケーションの設計を大幅に変更しています。


良い提案。私はそのような変更を行う際にも、ここでの提案に他の人を参照してください。code.google.com/p/autofac/wiki/ExistingApplications
Kalebペダーソン

7

ピックアップレガシーコードで有効に機能し、彼のアドバイスに従ってください。カバーされたコードのアイランドを構築することから始め、より適切に構造化されたアプリケーションに徐々に移行します。一斉に変化を起こそうとすることは災害のレシピです。


その本が大好きです!!
Martijn Verburg、2011年

良い推薦。その半分は数年前に読んだものですが、腰が深くなっているので、今ではもっと多くのことを学べると思います。
Kaleb Pederson、2011年

おかしいです、選択された回答は基本的に本を要約したものです;)もちろんFeathersははるかに詳細になります。
マイケルブラウン

5

IoCを導入する主な理由は、モジュールの分離です。特にJavaの問題は、newオペレーターが提供する並外れた強力なバインディングと、呼び出しコードが使用するモジュールを正確に認識しているということです。

工場はこの知識を中心的な場所に移動するために導入されましたが、最終的newには、ハードバインディングを維持する/ singletonを使用してモジュールをハードワイヤーするか、構成ファイルを読み込んでリファクタリング時に脆弱なReflection / Class.forNameを使用します。

ターゲットがモジュール化されていない場合、IoCは何も提供しません。

ユニットテストを導入すると、これはおそらく変更されます。テストされていないモジュールをモックアウトする必要があるためです。これと同じコードで実際の本番モジュールを処理する最も簡単な方法は、IoCフレームワークを使用して適切なモジュール。

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