XNA Game Servicesと栄光のグローバル変数の違いは何ですか?


10

このMicrosoft.Xna.Framework.Gameクラスには、プログラマーがクラスのタイプとクラスのインスタンスをAddメソッドに提供することによってゲームにサービスを追加できるようにするServicesプロパティがあります。

これで、AudioComponentを必要とするすべてのクラスとメソッドにを渡す代わりに、Gameインスタンスを渡してサービスを検索するだけです。(サービスロケーター

ゲームには多くのサービス(GraphicsDevice、SceneGraph、AudioComponent、EffectsManagerなど)があるため、基本的にはすべてにGameを渡します。

では、なぜこれらのインスタンスをシングルトンにしないのですか?まあ、シングルトンはグローバルな状態を持ち、テストを防ぎ、設計をはるかに脆弱にするため、悪いからです。サービスロケーターは、オブジェクトへの依存関係を渡すだけでなく、そのクラスを他のサービスと結合するサービスロケーター(ゲーム)を渡すため、多くの人にとってアンチパターンと見なされます。

では、なぜXNAおよびゲーム開発でサービスが推奨されるのでしょうか。それは、ゲームが通常のプログラムとは異なり、それらのコンポーネントと密接に絡み合っており、クラスの機能に必要なすべてのコンポーネントを渡す必要が非常に煩雑になるためでしょうか?そのとき、ゲームサービスはゲームデザインに必要な悪ですか?長いパラメーターリストと結合を含まない代替手段はありますか?


3
「サービスロケーターは多くの人にとってアンチパターンであると同様に考えられている」-[引用が必要]。明らかに、必要のない場所でそれらを使用することは悪いことです-すべてのソフトウェア構成に当てはまります-アンチパターンと呼ばれるサービスロケーターを聞いたことがありません。(その一方で、最新のパターンの詳細について話し合うことにほとんどの時間を費やすプログラマーも避けようとします。)

@JoeWreschnig私はあなたに同意しますが、いくつか掘り起こしてこれを見つけました:blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
Roy T.

2
はい、でもその人はDIの使用に関する本を販売しています。明らかに、彼はあなたにシンプルなものを使わせたくないので、あなたは彼の本を買わないでしょう!(真剣に、Fowlerの最初のDI / SL記事はこの正確なトピックをカバーしていました-martinfowler.com/articles/…-そしてその男のブログの

マーティンファウラーから投稿したばかりのリンクを回答としてマークできればいいのですが(私の質問ではありません)
Roy T.

回答:


6

サービスロケーターが悪いことに誰もが同意しているとは思いません。サービスロケーターは、誰もが必要とする重要な機能を実際の実装から切り離す方法を提供します。サービスロケーターは、実行時にサービスを交換する方法も提供します。また、サービスロケータをあちこちに渡さなければならないというのは本当ではないと思います。どこからでもアクセスできると思います。グローバルのあるゲームクラスは、フレームごとに約1000回渡す必要があります(パフォーマンスが低下します)。

サービスロケーターとグローバルを持つクラスの違いをもう少し明確にするには、次の例を検討してください。

ゲームを作成し、グローバル変数(コンテンツローダー)を持つgameAクラスオブジェクトを使用しています。次のゲームでは、gameAクラスを使用せずに、新しいgameBクラスを作成します。今度は、gameAのグローバルをgameBに再度追加する必要があります。これは余分な作業です。また、必要なタイプのコンテンツローダーを構成するのが難しくなります。PCとXBOXの両方で実行されるゲームがあるとします。PCでは、「ファイルを開く」ダイアログを開くこともできるコンテンツローダーが必要です。XBOXにいる間、私は間違いなくこれを望まない。設定ファイルを作成することで、gameAのグローバルをすべてパブリックにするだけでなく、gameAクラス以外の場所からでも、ゲームの途中からコンテンツローダーを簡単に変更できます。

ここで、サービスロケータを使用していることを検討してください。いつでも使い続けることができます。また、どのようなサービスが存在する場合でも、常に異なる可能性があります。彼らが共通のインターフェースを持っている限り、私はそれらの実装さえ気にしないことも真実です。(クラスのようなgamAでも使用できますが)。

とにかく、ゲームサービスはかなり便利だと思います。私が知っている誰もがそれを使用しています。あなたをもう少し助けるために。ゲームサービスの周りに小さなヘルパークラスを作成しました。これにより、キャストをずっと少なくできるようになります。http//roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager -and-graphicsdevice-anywhere-anytime-the-gameservicecontainer /私はかなり頻繁に使用しています。


返信いただきありがとうございます。サービスを必要とするクラスでは、通常、必要なときにいつでもサービスのGameServicesクラスを要求するだけですか、それともクラスでメンバー変数を作成し、コンストラクターでのみサービスを要求しますか?私が尋ねていることは、どれほど遅いかだと思いますreturn (T)Instance.GetService(typeof(T));
John Pollick、2011年

また、GameServicesクラスのこの実装についてどう思いますか?抽象化にはまだない機能がなかったので、不要なシングルトンを削除しました。また、Serviceすべてのメソッドの最後にある冗長なサフィックスを削除しました。
John Pollick、2011年

また、Services AddServiceメソッドが型を取るのは、サービスのインターフェースを指定できるようにするためだと思います。たとえば、Services.AddService(typeof(IGraphicsDeviceManager), graphics);。次に、サービスを取得するときに、インターフェイスをタイプとして指定し、選択したサブクラスにキャストできます。
John Pollick、2011年

@JohnPollick、最初の質問。私は常にそれを要求しようとします(それが変更された可能性があるため)が、本当にすべてのフレームで何かが必要な場合は、メンバー変数を作成します。パフォーマンス統計があまりないので、それがボトルネックになることはありません。第二に、ええ、それはうまく見えます:)。そして、3番目。これが実際に型引数の理由ですが、サービスとしてクラスをスワップする機能を破壊するため、取得した値をダウンキャストする習慣をつけてはなりません。IGraphicsDeviceMangerが不要でMyGDMが必要な場合は、新しいインターフェイスを作成してください。
ロイT.

1
ああ、私もあなたがキャストされているのを見ませんでした。もちろん、最初にキャストすれば、タイプを推測できます:)。
ロイT.

5

では、なぜこれらのインスタンスをシングルトンにしないのですか?まあ、シングルトンはグローバルな状態を持ち、テストを防ぎ、設計をはるかに脆弱にするため、悪いからです。

シングルトンは一般に、多くの有用な特性を取り、それらをひどいハイブリッドにパッケージ化します。これにより、望まないいくつかのことと、望まれたどのビットでも提供します。(「オンデマンド作成」の特徴でしたか?グローバルスコープですか?少なくとも1つのインスタンスの強制?複数インスタンスの禁止?)

サービスロケーターは、オブジェクトへの依存関係を渡すだけでなく、そのクラスを他のサービスと結合するサービスロケーター(ゲーム)を渡すため、多くの人にとってアンチパターンと見なされます。

完全に結合することは避けられません。物事は他のものを使用し、それなしではプログラムは何もしません。したがって、唯一の真の問題は、それがどの程度の抽象化レベルにあるかです。

オブジェクト指向に関するほとんどのテキストは、コンポジションとアグリゲーションを区別しています。自分が所有しているものと自分が知っているものの概念的な違いを理解することが重要です。残念ながら、最近のほとんどの言語には明確な区別がないため、オブジェクトへの参照はこれらのいずれかを意味する可能性があります。(皮肉にも、さまざまなスマートポインタ型を使用すると、C ++の方が優れています。)

あなたが1つの方法ことができ、あなたのコード内の組成と集約を明確にするには、集約されたオブジェクトのためのサービスを使用することです。サービスは、所有していないが使用できるものへのアクセスを提供する1つの方法です。

では、なぜXNAおよびゲーム開発でサービスが推奨されるのでしょうか。

ゲーム開発で広く推奨されているとは思いません。

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