DI / IoCを使用すると、「新しい」キーワードの出現をすべて削除する必要がありますか?


21

Dependency InjectionとInversion of Controlコンテナを使用すると、コードから" "キーワードがすべて削除さnewれますか?

言い換えれば、どのオブジェクト/依存関係も、どれほど単純または短命であっても、IoCコンテナー内に「登録」し、それらを使用する必要があるメソッド/クラスに注入する必要がありますか?

いいえの場合、依存関係/オブジェクトがIoCコンテナに登録される線と、具体的な参照として「インライン」で作成されるものとの間に、newキーワードを介してどこで線を引きますか?


「 'new'は4文字の単語ですか?」という行に沿って、私は同じ考えを持っていました。
マイケルイースター

回答:


27

教義を避けてください。正しいと思うことをしてください。

動作のないデータ構造には「新規」を使用することを好みます。

クラスに動作がある場合、その動作のスコープを調べます。ステートレスで依存関係がない場合、「新しい」方向に傾いています。ステートフルリソース(データベースやファイルなど)、またはそのようなリソースを持つ他のクラスに依存関係を追加する必要がある場合にのみ、DIへのリファクタリングを開始します。


15
「ドグマを避ける」ための+1。何が起こっているのか、どこで適切に使用すべきなのかを理解せずに、動きを追跡するだけのtrapに陥りやすい。
ウェインモリナ

@アレックスこれが好きです。非常に実用的なアプローチ。おもしろいことに、質問にコードを追加newして、自分のコードに「ed依存関係」を表示して、質問を促しました。それは機能も「振る舞い」それ自体もなく、単純なプロパティのみを持つ単純なクラスでした。
CraigTP

11

私の本は、私は安定したとの区別を提供揮発性の依存関係を。揮発性依存関係でDIを使用することは最も重要ですが、多くの場合、安定した依存関係を抽象化して注入することで、さらに緩やかな結合を実現できます。

DIのアプリケーションはDIコンテナに依存してはならないことに注意してください。場合には貧乏人のDIが使用中で、何のnewキーワードは削除されません-彼らはちょうどに移動されているコンポジションのルート

実際、DIコンテナよりも貧乏人のDIを好む人もいます。メンテナンスコストは高くなる場合がありますが、代わりにコンパイル時の安全性が得られます。私が最近聞いたように、ダン・ノースは言う:「new新しいnew」:)

これが意味するのは、DIコンテナでコンポジションルートを実装するのではなく、ネストされたnewステートメントの束が含まれているだけです。


マーク、Twitterのコメントを少し広げてみると、プログラマーは、実装の特定のエラーを扱っていない概念的なホワイトボードの質問に適した場所です。
アダムリア

3
Stack Overflowには、dependency-injectionタグに2000以上の質問があり、それらの多くはこのようなものです。プログラマーには、同じタグに23の質問があります。これらの数値に基づいて、開発者はこのような質問に対する答えを得る最大のチャンスをどこに持って行くべきですか?
マークゼーマン

1
これらの質問の多くは、プログラマーに完全に先行します。このサイトは、SOから概念的な質問を取り除き、専用のホームを提供するために作成されました。そして、私たちはまだ成長しています。進行中の作業ですが、理想的には、特定の実装の問題を含まない質問はここに移行されます。その間にできることをします。
アダムリア

3

「新規」は禁止キーワードではありません。私の個人的なルール:

すべての「サービス」(1つだけの事柄に関連する1つ以上のメソッドを提供するように設計されたクラスをサービスと呼びます。たとえば、データベースへのアクセス、特定のドメインに関連するデータの取得/更新)は、IOCコンテナーに登録されます。どのクラスも、使用する必要のある特定のサービスの実装を取得する方法について決定する必要はありません。したがって、既存のサービスを使用する必要があるときはいつでも、クラスとIOCコンテナーを構成して提供する必要があります。あなたの実装がどのように機能するかを知らないことを想像してください。それはウェブサービスかもしれません、あなたは気にしません。

すべてのBean、またはモデルは、いくつかのデフォルトプロパティを有効にする必要がある場合、「new」キーワードまたはIOC登録済みファクトリで作成されます。静的メソッドのみを含むユーティリティクラスの特殊なケースもあります(例:数学的ユーティリティサービス)。それらが完全にスタンドアロンであり、データベース接続または別のIOC登録サービスを必要としない場合、IOCから除外し、静的に呼び出されます。ただし、そのようなクラスの1つが既存のIOC登録サービスを使用する必要がある場合は、それをシングルトンクラスに変更し、IOCに登録します。


2

先ほど紹介した既存の回答に追加したいのnewですが、純粋な値のオブジェクト(つまり、プロパティ/ゲッター/セッターのみ)を作成するのにまったく問題ありません。詳細については、Google Testing Blogをご覧ください。


リンクの+1。そのブログ投稿でポイント9が質問に答えるとし、すべきではないべきかの間に実用的な区別を提供new「編
CraigTP

1

明らかに、使用する言語に依存します。言語がオブジェクトを使用して実際のオブジェクトとレコード(値オブジェクト、構造体)の両方を表すように強制する場合、答えはおそらく「いいえ」です。

純粋に「実際の」オブジェクトと言えば、インスタンスを明示的に作成しても何も問題はありません。ただし、心に留めておく必要があるのは、すべてのクラスが単一の責任原則に従う必要があるということです。依存するサービスの実装者を選択することは、クラスの責任であってはなりません。ただし、特定のサービスの実装者を提供するという、まさにその責任を持つクラスがあります。IoCはそのようなクラスかもしれません。実際、どのタイプのファクトリーもそのようなクラスです。

要約すると、このようなクラスのみがオブジェクトを直接インスタンス化する必要があり、インスタンス化するクラスを選択するのは誰の責任です。
次の基準が役立つ場合があります。http//en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Creator


1

一言:いいえ。

より多くの言葉:依存性注入はまさにそれです。これは、別のオブジェクトが依存しているリソースを導入する手段ですが、別のソースからの複雑な詳細を知る必要はありません。DIを使用することは、プログラムでNOTHINGが他のオブジェクトの作成方法を知っている必要があることを意味しません。実際、重要なプログラムでは「新しい」キーワード(またはリフレクションベースの代替)を完全に回避することは非常に実行不可能だと思います。ただし、DIは、このオブジェクトを他のオブジェクトに緊密に結合する多くの依存関係を必要とする複雑なオブジェクトを作成する方法を知ってはならないオブジェクトが、このような密結合の知識をすべて持っているべきではないことを意味します。

O / Oソフトウェア設計の2つの主要な理論、GRASPとSOLIDを勉強します。GRASPは、オブジェクトの目的を研究するように指示し、「このオブジェクトはこの他のタイプの新しいオブジェクトの作成を担当する必要がありますか?そのオブジェクトの「ジョブ記述」の一部ですか?」SOLIDはさらに一歩進んでいます。「S」は「単一責任原則」の略で、オブジェクトには1つのジョブが必要であり、その特定のジョブを実行するプログラム内の唯一のオブジェクトであることを明確に示します。

したがって、GRASPは一般に、これらの新しいオブジェクトを作成する既存のクラスを調べ、目的のレベルの「凝集」を維持しながら、このオブジェクトを作成するタスクがオブジェクトが既に行っていることに適合するクラスを見つけることを推奨します。SOLIDは、凝集が重要であることを示します。これらのオブジェクトを作成するタスクは、クラスに注入する必要のあるファクトリーに与える必要があります。プログラムの複雑さが増すにつれて、これらの方法論のいずれかを順守し、リファクタリングを行うと、非常によく似たアーキテクチャが得られると思います。

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