小売ゲームは「制御の反転」と「依存性注入」を使用していますか?


30

私が知っているより勤勉なソフトウェア開発者の多くは、オブジェクトへの参照を処理するために、制御の反転依存性注入に移行しています。Flashゲームの観点から言えば、私はAAAスタジオのすべてのインとアウトを知らないので、これらは小売ゲームの世界で使用されていますか?


その世界ではパフォーマンスは何よりも重要だと思います。なぜなら、プログラマーよりも悪いコードによってパフォーマンスが低下するユーザーの方が多いからです。
バートヴァンヒューケロム

依存性注入はコンポーネントベースのシステムのように聞こえますが、制御の反転を解除する方法の例はありますか?
ADB

このスレッドのほとんどはIoCとは何か、それが解決するものについて誤解されているようであり、OPはそもそも将来の訪問者のためにここでポイントすることを求めていません:sebaslab.com/ioc-container-unity-part-1
ボリスCallens

はい、彼らがやります。-実際には、レアは、彼らは泥棒の海で彼らのテストを実施しているかについての話だったyoutube.com/watch?v=KmaGxprTUfI&t=1sを。残念ながら、彼らはUnreal EngineのInversion of Controlについてあまり語ることはできませんでしたが、それがどのように機能するかを示すプロジェクトを作成しました:github.com/jimmyt1988/UE-Tes​​ting
Jimmyt1988

回答:


45

あなたはそれを「勤勉なソフトウェア開発」と呼び、私はそれを「苦痛なオーバーエンジニアリング」と呼んでいます。それは、制御の反転が悪いと言うことではありません-実際、それの基本的な定義は良いです-しかし、全体のフレームワークとこれを達成するために働く方法の全体の拡散は、特に人々がゴミを捨てる方法と組み合わせて、非常識に少し不足しています99%の確率で交換できないコンポーネントを交換できるようにするための、完全に良好でクリーンなインターフェース。これは、Javaエンタープライズ環境からのみ発生する可能性がある種類のものであり、他の場所に足場があまりないことを嬉しく思います。

多くの場合、コンポーネントを交換しなくても、モックオブジェクトなどを使用してコンポーネントを分離してテストできるようにしたいという意見があります。しかし、インターフェイスを肥大化させて複雑にする価値があり、それをテストできるようになるという議論を決して買うつもりはありません。テストが証明するのは、テストが機能することだけです。一方、クリーンで最小限のインターフェイスは、コードが機能すること証明するのに役立ちます。

簡単な答え:はい、しかしあなたが考えている方法ではありません。時々、交換可能な動作が必要な場合、新しいオブジェクトの動作の一部を指示するコンストラクターにオブジェクトを渡します。それについてです。


5
+1-Javaコミュニティが、非常に単純なアイデアと思われるものを大幅に複雑化しすぎているように見えることに同意します。
クリス・ハウ

4
アイデアは、必ずしも実稼働環境で異なる実装を交換する必要があるというわけではありませんが、自動テストを容易にするために特別な実装を挿入することもできます。その点で、DI / IoCは確かにゲームで役立つ可能性がありますが、適度にスコープを維持する必要があります。高レベルでの1回限りのサービス解決は数回しか必要ありません。ゲーム内の小さなオブジェクトごとにサービスを解決したくはありません。
マイクストロベル

2
@Thomas Dufour:テストの概念は何も証明できません。これは単なるデータポイントです。実行100001に合格することを証明せずに、テストに100000回合格することができます。証明は、主題の論理分析から得られます。これらのIoCコンテナーなどは、正確性の証明を難しくするという犠牲を払ってテストを容易にするものだと主張しますが、それは悪いことだと思います。
キロタン

13
@Kylotanでは、テストの概念は何も証明しようとしません。指定された入力での動作が予想どおりであることを実証しようとします。より多くの動作が正しいことが示されると、全体的な機能は正しいが100%ではないという確信が高まります。最小限のインターフェースが何でも証明するという声明はばかげている。
ダッシュトムバン

5
@Alex Schearer:正式なIoCコンテナシステムを使用し、通常はテストを容易にするために追加のコンストラクタ引数またはファクトリクラスを作成する必要があることを受け入れることはできません。結合を緩くします。実際、OOPの重要な側面であるカプセル化はほとんど踏みにじられています。TDDに依存して設計を推進し、良好な結果が得られることを期待する代わりに、人々はそもそもSOLID原則に従うことができます。
キロタン

17

Strategy PatternCompositionDependency Injectionは、すべて非常に密接に関連しています。

戦略パターンは依存性注入の形式であるため、たとえばUnityのようなエンジンを見ると、この原則に完全に基づいています。コンポーネント(戦略パターン)の使用は、エンジン全体に深く組み込まれています。

コンポーネントの再利用以外の主な利点の1つは、恐ろしい深いクラス階層を避けることです。

これが、Mick Westによる、NeversoftのTony Hawkシリーズのゲームにこのタイプのシステムを導入した方法についての記事です。

階層を進化させる

かなり最近まで、ゲームプログラマは一貫して深いクラス階層を使用してゲームエンティティを表現してきました。潮流は、この深い階層の使用から、コンポーネントの集合としてゲームエンティティオブジェクトを構成するさまざまなメソッドへとシフトし始めています...


2
+ 1、Evolve Your Hierarchyは、私が完全に忘れていた素晴らしいリンクです。スコット・バイラスのスライドも優れています-これらの正しいリンクは(scottbilas.com/files/2002/gdc_san_jose/game_objects_slides.pdf)です。...そこ以上の関連スライドのセット1ですが、私はどこ忘れてしまった
リアンダー

Bjarne ReneによるGames Gems 5(と思う)の記事も。
クリス・ハウ

13

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。メソッドをテストするには、次のものが必要です。

  1. 適切なファイルシステム
  2. ファイルシステムからロードするテストファイル
  3. 一般的なファイルシステムエラーをトリガーする機能

最初の2つは明らかですが、エラー処理が期待どおりに機能することを確認したい場合は、本当に#3も必要です。どちらの場合も、ディスクに移動する必要があるため、テストの速度が大幅に低下する可能性があり、テスト環境をより複雑にした可能性があります。

IoCの目標は、動作の使用をその構築から切り離すことです。これが戦略パターンとどのように異なるかに注意してください。Strategyパターンの目標は、再利用可能な動作の塊をカプセル化して、将来簡単に拡張できるようにすることです。戦略がどのように構築されるかについては言うまでもありません。

Sprite.Load上記のメソッドを書き換えると、おそらく次のようになります。

class Sprite {
    void Load(IReader reader) {
        // load image through reader
    }
}

これで、リーダーの構成をその使用から切り離しました。したがって、テスト中にテストリーダーを交換することができます。これは、テスト環境でファイルシステムやテストファイルが不要になり、エラーイベントを簡単にシミュレートできることを意味します。

リライトでは2つのことを行ったことに注意してください。IReaderいくつかの動作をカプセル化したインターフェースを作成しました。つまり、Strategyパターンを実装しました。さらに、適切なリーダーを作成する責任を別のクラスに移しました。

上記を説明するために新しいパターン名は必要ないかもしれません。IoCコンテナ用のStrategyパターンとFactoryパターンが混在しているように感じます。そうは言っても、このパターンが実際の問題を解決することは明らかであるため、人々がこのパターンに反対している理由はわかりません。


2
アレックス:必要に応じてカスタム機能を実行するために、既に作成されたオブジェクトを渡すことに反対する人はいません。あなたの例のように、誰もがそれを行います。問題は、人々が純粋に存在するフレームワーク全体を使用してこのようなものを処理し、この機能に依存するように機能のあらゆる側面を宗教的にコーディングしているところです。彼らは、最初のこのような態度は、など、Javaと春のIoCコンテナのようなものから発生しないなど、スプライトの建設にパラメータとしてIReaderを追加し、これを容易にするために、特別なSpriteWithFileReaderFactoryオブジェクトを必要としてしまう
Kylotan

2
しかし、私たちはIoCコンテナについては話していません-少なくとも、元の記事では見ていません。私たちはただパターンそのものについて話しているだけです。私が言うことができるように、あなたが主張しているのは、「野生のいくつかのツールが悪いので、基礎となる概念を使用すべきではない」ということです。それは、お風呂の水で赤ちゃんを投げ出すように私を打つ。シンプルさ、物事の達成、および保守性/テスト容易性の適切なバランスをとることは、プロジェクトごとにプロジェクトで最も適切に対処される難しい問題です。
アレックスSchearer

多くの人がIoCに反対しているのは、次のことを意味しているのではないかと
思われます。– phtrivier

4

私はそれが多くのツールのうちの1つであり、時々使用されると言うでしょう。tenpnが言ったように、vtables(および一般に余分な間接化)を導入するメソッドはパフォーマンスの低下を招く可能性がありますが、これは低レベルのコードについてのみ心配すべきことです。高レベルの構造コードについては、実際には問題ではなく、IoCにはプラスのメリットがあります。クラス間の依存関係を減らし、コードをより柔軟にするもの。


2
正確には、フレームで何度も呼び出されるコードのvtableペナルティが心配です。これは低レベルである場合とそうでない場合があります。
tenpn

4

これについては、Kylotanに同意する必要があります。「依存性注入」は、JavaいJavaの概念的な欠陥に対するいJavaソリューションであり、他の言語でそれを見ている人がいる唯一の理由は、Javaが多くの人にとって最初の言語になっているからです。

一方、制御の反転は、長い間使用されてきた有用なアイデアであり、適切に行うと非常に役立ちます。(Java / Dependency Injectionの方法ではありません。)実際、正気のプログラミング言語で作業しているのであれば、おそらく常にそれを行っているでしょう。誰もが話題になっているこの「IOC」のこと全体を最初に読んだとき、私は完全に圧倒されました。制御の反転とは、その動作をカスタマイズするために、ルーチンまたはオブジェクトに関数ポインター(またはメソッドポインター)を渡すことです。

これは、1950年代以来のアイデアです。C標準ライブラリ(qsortが思い浮かぶ)にあり、Delphiおよび.NET(イベントハンドラー/デリゲート)のいたるところにあります。これにより、古いコードを再コンパイルする必要なく新しいコードを呼び出すことができ、ゲームエンジンで常に使用されます。


2
私は「これが人々が興奮しているものなのか」ということでもありました。私がDIについて読んだとき、実際には、ほとんどのゲームプログラマーがDIについて学び、それが私たちの仕事にどのように適用されるかについて学ぶことができました。
ダッシュトムバン

2

私の経験ではありません。ゲームのコードは非常に適応性が高い必要があるため、これは残念です。これらのアプローチは間違いなく役立ちます。

ただし、C ++では、両方のメソッドが以前には存在しなかった仮想テーブルを導入し、適切なパフォーマンスヒットをもたらす可能性があると言わなければなりません。


1

私はプロのゲーム開発者ではありません。C++でIoCを実装したのは一度だけなので、これは推測にすぎません。

ただし、ゲーム開発者はIoCについて疑わしいと思われます。

1 /多数のインターフェイスと多数の小さなクラスの設計

2 /ほとんどすべての関数呼び出しが最近バインドされている

偶然かもしれませんが、どちらもIoCが普及したJavaよりもC ++(ゲームで広く使用されていますよね?)比較的簡単だったので、人々が健全なオブジェクト階層を設計するのを助け、Javaでアプリケーションを書くことをXMLでアプリケーションを書くことに変えることができると信じていたので、それは別の議論です:P)

それがまったく意味をなさない場合、私はコメントに興味があります;)

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