私が知っているより勤勉なソフトウェア開発者の多くは、オブジェクトへの参照を処理するために、制御の反転と依存性注入に移行しています。Flashゲームの観点から言えば、私はAAAスタジオのすべてのインとアウトを知らないので、これらは小売ゲームの世界で使用されていますか?
私が知っているより勤勉なソフトウェア開発者の多くは、オブジェクトへの参照を処理するために、制御の反転と依存性注入に移行しています。Flashゲームの観点から言えば、私はAAAスタジオのすべてのインとアウトを知らないので、これらは小売ゲームの世界で使用されていますか?
回答:
あなたはそれを「勤勉なソフトウェア開発」と呼び、私はそれを「苦痛なオーバーエンジニアリング」と呼んでいます。それは、制御の反転が悪いと言うことではありません-実際、それの基本的な定義は良いです-しかし、全体のフレームワークとこれを達成するために働く方法の全体の拡散は、特に人々がゴミを捨てる方法と組み合わせて、非常識に少し不足しています99%の確率で交換できないコンポーネントを交換できるようにするための、完全に良好でクリーンなインターフェース。これは、Javaエンタープライズ環境からのみ発生する可能性がある種類のものであり、他の場所に足場があまりないことを嬉しく思います。
多くの場合、コンポーネントを交換しなくても、モックオブジェクトなどを使用してコンポーネントを分離してテストできるようにしたいという意見があります。しかし、インターフェイスを肥大化させて複雑にする価値があり、それをテストできるようになるという議論を決して買うつもりはありません。テストが証明するのは、テストが機能することだけです。一方、クリーンで最小限のインターフェイスは、コードが機能することを証明するのに役立ちます。
簡単な答え:はい、しかしあなたが考えている方法ではありません。時々、交換可能な動作が必要な場合、新しいオブジェクトの動作の一部を指示するコンストラクターにオブジェクトを渡します。それについてです。
Strategy Pattern、Composition、Dependency Injectionは、すべて非常に密接に関連しています。
戦略パターンは依存性注入の形式であるため、たとえばUnityのようなエンジンを見ると、この原則に完全に基づいています。コンポーネント(戦略パターン)の使用は、エンジン全体に深く組み込まれています。
コンポーネントの再利用以外の主な利点の1つは、恐ろしい深いクラス階層を避けることです。
これが、Mick Westによる、NeversoftのTony Hawkシリーズのゲームにこのタイプのシステムを導入した方法についての記事です。
かなり最近まで、ゲームプログラマは一貫して深いクラス階層を使用してゲームエンティティを表現してきました。潮流は、この深い階層の使用から、コンポーネントの集合としてゲームエンティティオブジェクトを構成するさまざまなメソッドへとシフトし始めています...
Inversion of Control(IoC)パターンに関して多くの混乱があるようです。多くの人々がそれを戦略パターンまたはコンポーネントモデルと同一視していますが、これらの比較は実際にはIoCが何であるかを把握していません。IoCは、実際に依存関係を取得する方法に関するものです。例を挙げましょう。
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
上記でSprite.Load
は、に依存していることが明らかですFileReader
。メソッドをテストするには、次のものが必要です。
最初の2つは明らかですが、エラー処理が期待どおりに機能することを確認したい場合は、本当に#3も必要です。どちらの場合も、ディスクに移動する必要があるため、テストの速度が大幅に低下する可能性があり、テスト環境をより複雑にした可能性があります。
IoCの目標は、動作の使用をその構築から切り離すことです。これが戦略パターンとどのように異なるかに注意してください。Strategyパターンの目標は、再利用可能な動作の塊をカプセル化して、将来簡単に拡張できるようにすることです。戦略がどのように構築されるかについては言うまでもありません。
Sprite.Load
上記のメソッドを書き換えると、おそらく次のようになります。
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
これで、リーダーの構成をその使用から切り離しました。したがって、テスト中にテストリーダーを交換することができます。これは、テスト環境でファイルシステムやテストファイルが不要になり、エラーイベントを簡単にシミュレートできることを意味します。
リライトでは2つのことを行ったことに注意してください。IReader
いくつかの動作をカプセル化したインターフェースを作成しました。つまり、Strategyパターンを実装しました。さらに、適切なリーダーを作成する責任を別のクラスに移しました。
上記を説明するために新しいパターン名は必要ないかもしれません。IoCコンテナ用のStrategyパターンとFactoryパターンが混在しているように感じます。そうは言っても、このパターンが実際の問題を解決することは明らかであるため、人々がこのパターンに反対している理由はわかりません。
これについては、Kylotanに同意する必要があります。「依存性注入」は、JavaいJavaの概念的な欠陥に対するいJavaソリューションであり、他の言語でそれを見ている人がいる唯一の理由は、Javaが多くの人にとって最初の言語になっているからです。
一方、制御の反転は、長い間使用されてきた有用なアイデアであり、適切に行うと非常に役立ちます。(Java / Dependency Injectionの方法ではありません。)実際、正気のプログラミング言語で作業しているのであれば、おそらく常にそれを行っているでしょう。誰もが話題になっているこの「IOC」のこと全体を最初に読んだとき、私は完全に圧倒されました。制御の反転とは、その動作をカスタマイズするために、ルーチンまたはオブジェクトに関数ポインター(またはメソッドポインター)を渡すことです。
これは、1950年代以来のアイデアです。C標準ライブラリ(qsortが思い浮かぶ)にあり、Delphiおよび.NET(イベントハンドラー/デリゲート)のいたるところにあります。これにより、古いコードを再コンパイルする必要なく新しいコードを呼び出すことができ、ゲームエンジンで常に使用されます。
私はプロのゲーム開発者ではありません。C++でIoCを実装したのは一度だけなので、これは推測にすぎません。
ただし、ゲーム開発者はIoCについて疑わしいと思われます。
1 /多数のインターフェイスと多数の小さなクラスの設計
2 /ほとんどすべての関数呼び出しが最近バインドされている
偶然かもしれませんが、どちらもIoCが普及したJavaよりもC ++(ゲームで広く使用されていますよね?)比較的簡単だったので、人々が健全なオブジェクト階層を設計するのを助け、Javaでアプリケーションを書くことをXMLでアプリケーションを書くことに変えることができると信じていたので、それは別の議論です:P)
それがまったく意味をなさない場合、私はコメントに興味があります;)