web-dev-qa-db-ja.com

依存性注入:すべてのパーツを保持するCarクラスを作成する必要がありますか?

私のC++アプリケーションには多くの車があり、すべてRaceTrackに含まれています。

各車は何百ものパーツで構成されています。各部分は他の部分に依存しています。

私は多くのSO DIとMark Seemannの本についての質問を読みました、そしてそれは私がすべての自動車部品が互いに依存しているので自動車部品を保持するためだけに自動車クラスを定義すべきではないようですこのパーツのスープは車です。そうですか?

したがって、すべてのレーシングカーをRaceTrackに配置すると、自動車の実体はなく、トラック上で互いにレーシングしている相互に依存する多くの自動車部品がありますか?私は正しいですか?

編集:

私が車のロジックをプログラミングしている場合は車のクラスが必要であることは明らかだったので、長い間私は車のクラスをプログラミングしていました。しかし、DIでは、それは私にはそれほど明白ではありません。 Carクラスが定義されていない場合にCarクラスを作成しないのは、DIの慣用句ですか?

車全体を表すインスタンスがなくても、運転用のSteeringWheel、ピットクルー用のホイールにBoltsAndNuts、その他のさまざまな面白いインターフェースがあっても問題ありませんか?

10
Anton Petrov

誰かがレーストラックに座っている車のパーツの束は何がいいですか?

あなたの車のクラスのすべてが車の部品を保持している場合、それは部品のウェットバッグと同じくらい便利です。

使用法

ドライバーとして私が欲しいのは私がコントロールできるものです。それは私がスピードを求めるときに反応します。これはon Railsのように処理します。それは10セントで止まることができます。

私が欲しいのは、使える車のクラスです。キャブレターがどのように機能するかを考える必要なく物事を行うために私が言うことができること。アクセルペダルについて考えてみます。それらがどのように接続されているかは私が心配することではありません。それは抽象化です。

依存性注入

依存性注入 はそれとは関係ありません。私は車を運転しているとき、それがどのように構築されたかについては考えていません。それが機能する限り、私は彼らがそれをどのように組み合わせるかを気にしません。

いいえ、DIは、ピットクルーがトラック上で雨が降り始めたときに、すぐにタイヤをより良いタイヤに交換できるようにするものです。まったく別の車に飛び込むことなくそれができるのは素晴らしいことです。

DIは実際には、原則に従うことです。

時速90マイルで新しいタイヤを取り付けることができる車はクールに聞こえるかもしれませんが、タイヤが取り付けられており、それを装着してレースに勝つことはできないと思います。

DIは、ピットクルーがパーツにアクセスできるようにパーツを取り付けることです。同じ場所でnewを使用すると、キャブレターを所定の位置に溶接しているように動作をプログラムします。確かにアセチレントーチはそれを取り除くことができますが、最初にナットとボルトの使用を検討してください。

それがDIです。確かに、あなたがそれを望んでいることに気づいてすぐに何かを_newするほど簡単ではありません。代わりに、車の組み立て方法を知っている別のコードを書く必要があります。ただし、後で変更するのが簡単になります。そしてそれはあなたがあなたと一緒にトラックの周りに自動車組立工場を引きずる必要がないことを意味します。

建設

どこかで、タイヤがグッドイヤーかどうかを知る必要があります。それでは、車の建設コードをどこに置くのですか?車でない場合、ピットクルーは?いいえ、トラック?いいえ。これらすべてに動作コードがあります。レース中に実行する必要があるコード。車の組み立ては、行動コードから削除された場所でレース前に行われる必要があります。 Mark Seemansがこの場所を Composition Root と呼びました。ほとんどの人はそれをメインと呼んでいます。

シンプルなパターンです。主に、オブジェクトグラフを作成してから、オブジェクトグラフ内の1つのオブジェクトに対して1つの動作メソッドを呼び出します。それでおしまい。これは[〜#〜] only [〜#〜]の場所の構造と動作を一緒にする必要があります。

これは、構造がすべてメインで順番に配置された手続き型コードの山でなければならないという意味ではありません。言語のすべてのツールを自由に使用して作成できます。行動と混同しないでください。

これを言語で行い、DIフレームワークやIoCコンテナーを使用しないことを pure DI と呼びます。それは非常にうまく機能します。長い間持っています。以前は単に 参照渡し と呼んでいました。

DIツール

DIツールが購入するのは、構築と動作の分離を強制する別の言語(xml、jsonなど)に移動された構築の詳細です。同僚のプログラマがnewを使用してはいけないときに信用していない場合は、魅力的です。

欠点は、DIツールの詳細をコードベース全体に行き渡らせたくなることです。時々、コードベースを独自のアノテーションで感染させる。彼らが提供する例は確かにこれを奨励しています。このツールは、ジョブをJavaプログラミングジョブとしてだけでなく、Java/Springプログラミングジョブとして宣伝することができないまで、言語スペースに移動する傾向があります。

設計原則

車のロジックをプログラミングしている場合は車のクラスが必要であることは明らかだったので、長い間私は車のクラスをプログラミングしていました。しかし、DIでは、それは私にはそれほど明白ではありません。 Carクラスが定義されていない場合にCarクラスを作成しないことは、DIの慣用句ですか?

抽象化について学び、クラスが必要であると判断する方法を変更していると思います。それは良い。しかし、それはDIの問題ではありません。 DIは、車のクラスが必要かどうかを判断するのに役立ちません。 DIは、タイヤがグッドイヤータイヤである場合に、車が気付かないようにするのに役立ちます。 DIは、トラックが日本製かどうかをトラックが知らないようにするのに役立ちます。

ソフトウェア設計における最も基本的な質問の1つは、「何について何を知っているか」です。これが、UMLダイアグラムで示される主なものです。あなたが到達している何かを新しくするとき、それはあなたが今結びついている具体的なものへのインターフェースです。車はタイヤがグッドイヤーであることを知る必要があります。ミシュランがあなたを後援したいなら、どれがうんざりするでしょう。

依存関係の逆転の原則 に従って、それを回避することが呼び出されます。正式には、(carクラスのような)高レベルモジュールは(GoodyearTireクラスのような)低レベルモジュールに直接依存すべきではありません。 (Tireインターフェースのような)抽象化に依存する必要があります。

これを回避する方法は 制御の反転 と呼ばれます。ここでは、制御の流れを変更することに重点が置かれています。タイヤは車を動かしますか、それとも車はタイヤを動かしますか?これを正しい方法で考えると、車とタイヤを静的に結合することができなくなります。 DIは、制御の反転を追跡する1つの特定の方法です。

車のクラスが必要かどうかはわかりません。 「車のロジック」をプログラミングしている場合、どこにでも分散させるのではなく、それを保持する場所が1つあればいいのです。車の構築ロジックは車の動作ロジックと同じだと考えて騙されないでください。すべて同じ場所に住んでいる必要があります。ただし、車のロールが定義されていない場合は、どちらも必要ありません。必要に応じて、トラックの周りでオートバイをレースします。

車全体を表すインスタンスがなくても、運転用のSteeringWheel、ピットクルー用のホイールにBoltsAndNuts、その他のさまざまな面白いインターフェースがあっても問題ありませんか?

DIまたはDIなし、車全体を表すインスタンスがあっても問題ありませんが、必要がない場合、そのインスタンスは直接知りたいものではありません。車の抽象化を教えてください。使用するときに、それがガス、ディーゼル、または電気で動くかどうか気にする必要はありません。それは私がそれを構築または維持しているときに私が気にする必要がある唯一のものです。 carを使用するコードがそれがどのように機能するかを知っていたり、気にする必要がない場合は、すばらしいことです。 「わからない。知りたくない」

24
candied_orange

すべての自動車部品は互いに依存し、この部品のスープは自動車であるため、自動車部品を保持するためだけにCarクラスを定義するべきではないようです。私は正しいですか?

番号。

依存関係注入のポイントは、依存関係を防ぐためにまったくないです。まったく逆です。

依存性注入は問題についてです:車はどこで部品を手に入れますかfrom?それらはどこでどのように作成され、車はどのように参照されますか?

単純に、自動車はnewを呼び出すことで部品自体を作成します。これは簡単で簡単ですが、非常に柔軟性がありません。車は部品を作成するために必要なすべてを知っている必要があり、異なる部品を持つ2台の車が必要な場合は、そのロジックも車に入れる必要があります。

依存関係の注入により、そのすべてのロジックが車から取り出され、構成コンポーネントに入れられます。これにより、すべてのパーツが作成され、参照が配線されます。完全に設定された依存関係は注入されたが車に-そしてお互いです。

15

したがって、すべてのレーシングカーをRaceTrackに配置すると、自動車の実体はなく、トラックでのレースに依存している多くの自動車部品がありますか?私は正しいですか?

上手。はいといいえ。車のエンティティはまだ有効です。そして、自動車はその部品の合計以上のものです。ドライバーも必要です(当面の間)。多くの場合、レースカーには車のメーカーとモデルは言うまでもなく、名前もあります。

はい、車は基本的にパーツのコンテナですが、何かを大きくするのは、このパッケージングとパーツの協力です。つまり、車です。

本当にそうです車は単なる金属とプラスチックのバッグではありません。それは機械です。

この場合、依存性注入は過剰ではありません。何かを車を構築する必要があります。これは、ファクトリクラスまたはビルダーオブジェクトになります。車はそれ自体を構築する方法を知らないはずです。

0
Greg Burghardt