XNAでGame1を静的にするのは悪い考えですか?


10

私のGame1クラスを静的として持つのは本当に悪い考えですか?現在のところ、私のGame1クラスにはTileHandler、現在のタイルのセットに関係AnimalHandlerするすべてを処理し、すべての動物を(驚くほど)処理するというクラスがあります。

ここでAnimalHandler、タイルが歩き可能かどうかをチェックしたい場合にTileHandler問題が発生するか、歩き可能なタイルのリストをに渡す必要がありますがAnimalHandler、これは行いません。

何容易になるだろうことは作ることになりGame1、静的をし、その後にAnimalHandlerだけ行きますGame1._tileHandler.WalkableTile(position)

これですぐに問題が発生したり、問題の原因となるものを確認したりすることはできませんが、静的クラスの使用を開始したばかりです。

回答:


9

これですぐに問題が発生したり、問題の原因となるものを確認したりすることはできませんが、静的クラスの使用を開始したばかりです。

光沢のある新しいハンマーを持っている場合、すべての問題は釘のように見えます。

一般に、適切に使用されていれば(インスタンスごとの状態を持たない、または依存しないもののために)静的クラスやメソッドに問題はありません。ただし、あなたの場合、インスタンスごとの依存関係を隠すためにそれらを誤用しており、これを依存関係の削除と混同しています。また、Game1クラスの実装の詳細を公開しているように見えますが、これも一般的に悪いことです。

ここにあなたの問題の核心があります:

...私が参加しAnimalHandlerていて、タイルがそれ以降にウォーク可能かどうかをチェックしたい場合、 TileHandler問題が発生するか、ウォーク可能なタイルのリストをに渡す必要がありますがAnimalHandler、これは行いません。

今のところ、AnimalHandlerこれらのタイルを必要とすること自体が悪いデザインである可能性を無視すると(選択した名前では、これらのクラスの詳細を伝えることは困難です)... AnimalHandlerウォーク可能なタイルのリストが必要な場合は、そのリストが必要です歩きやすいタイル。コードをより自己文書化するので一般的に依存関係をより明確にする方が適切です。リストを直接に渡すことにより、AnimalHandlerそのようなリストが必要であることを明示的に呼び出します。代わりにすべてを静的およびパブリックにして、コードの他の場所に保持されている静的リストにアクセスできるようにする場合は、実際に解決または削除せずに依存関係を非表示にするだけです。

これをスケールする必要のない小さなゲームの場合、それ自体は問題にはなりませんが、悪い習慣の道を進む可能性があるため、それを行わないことを検討する必要があります。少なくとも、次に取り組むプロジェクトでは、このことを覚えておいてください。


アーメン!私の答えではあまり触れなかった素晴らしい点に触れてください。
ネイト

+1依存関係の非表示とグローバル状態の導入は、ここでの問題です
ashes999

4

静的コンテキストでTileHandlerを呼び出すことが最善の設計ではない理由は、それがなければ分離できる可能性がある設計のコンポーネントを結合するためです。

将来複数のTileHandlerを使用することを選択した場合、この変更に対応するために多くの作業を行う必要があります。

TileHandlerを削除する場合は、この変更に対応するために多くの作業を行う必要があります。

将来、現在のTileHandlerとは異なる方法でタイルを処理する別のレベル/ゾーンを構築するとします。次に、使用するタイル処理のメソッドを指定する方法が必要か、別のハンドラーを呼び出す必要があります。

TileHandlerがパラメーターとしてそれを使用するオブジェクトに渡された場合は、次に別のものを単に渡すか、後でそれを使用するオブジェクトに別のタイルハンドラーを設定することができます。

個人的には、静的なコンテキストからXNAゲームの多くのものにアクセスし、それらを複数持つことはないと思います。

次のゲームでゲームエンジンコードを再利用できるようにしたい場合は、現在静的として記述しているものの多くを書き直さなければならないでしょう。

要するに:

静的コンテキストを使用しない方がよい:

オブジェクトをできるだけパラメーターとして渡すと、ゲーム要素が分離され、現在または将来のプロジェクトでオブジェクトをより簡単に変更/再利用できるようになります。また、大量のコードの複雑さを少し簡単に管理することもできます(大規模なゲームのゲームクラスに何百もの静的マネージャーがあると考えてください)。

静的コンテキストを支持して:

静的コンテキストからオブジェクトを宣言してアクセスすると、数百の静的マネージャーを必要としない小さなゲームを簡単に作成できます。代わりに静的にアクセスされる1つ以上の追加パラメーターを必要としないことにより、多くのメソッドとコンストラクターを簡素化します。


2

単純なゲームとしてはそれほど悪い考えではないと思いますが、 http://www.nuclex.org/articles/4-architecture/6-game-components-and-game-services for相互通信するゲームコンポーネントを構築する方法についてのより良いアイデア


単純なゲームではなかった場合の問題について考えていただけませんか?
ハロルド

コードの可読性、テスト容易性、優れたアーキテクチャプラクティスは、それを回避することをお勧めします。
smnbss

2

TileHandlerやAnimalHandlerのようなもの私はゲーム画面により高いレベルを設定します。タイトル画面はTileHandlerにアクセスする必要がありますか?ゲームが最初に読み込まれたときに初期化されますか?おそらく違います。

XNA State Managementサンプルを確認してください。そこには多くのコードが含まれていますが、基本的なゲームは基本的に、ゲームの状態(または画面)のスタックを初期化するだけです。各画面は他の画面からかなり独立しており、ゲーム自体の簡易バージョンとして実行されます。PlayScreenは静的メンバーを持つことができるため、PlayScreenコンポーネントにアクセスできます。

基本のゲームでは、いくつかの静的要素を使用しますが、InputHelper、Log、Configリーダーなどの非常に低レベルなものです。これらはすべてのゲームでかなり標準的であるため、ベースエンジンをすばやく簡単に移植できます。画面は、実際のゲームロジックが発生する場所です。長い答えは短いです-いいえ、理論的には悪い考えではないと思います。静的にする方法に注意してください。先に進んで何かを静的にすると、気が変わった場合、それは膨大な作業になります。


0

ここで上げたポイントはすべて良いです。私の経験では(確かにゲームよりもビジネスアプリに重点が置かれています)、静的なクラスとメンバーの優れた用途があり、何度も使用しています。要件と複雑さが増すにつれ、これらの静的クラスをリサイクルし、インスタンスクラスに変換して、受け渡しを開始することに気づきました。

私が強調したいのは、静的クラスを使用してこのゲームを実現するのに役立つ場合は、それを試してみますが、それでも正しいことを実行してください:インターフェースまたは基本クラスを実装して、それを取り出して変換するのが簡単になります後でインスタンスクラスに追加します。

1オンスの予防は1ポンドの治療に値するので、静的クラスがあなたを縛り付けて、変更を困難にしないようにしてください。インターフェイスを実装する静的クラスを使用してメソッドをリファクタリングするのは非常に簡単なので、新しいインターフェイスパラメータを受け入れ、静的クラス参照の代わりにそのインターフェイスを使用します。


0

はい、それは一般的に常に悪い考えです。

変化するデータを含むオブジェクト(つまり、読み取り専用の定数とルックアップテーブル以外のもの)を静的クラスに変換することは、優れた設計が急務となる場所です。

  1. それは、モジュール性を殺し、コードの再利用の邪魔になる無計画な依存関係を促進します。ゲームのエディターを作成したいとしましょう。突然Game1、共有ライブラリに簡単に移動できないクラスがたくさん出てきます。

  2. コードはテストできなくなります。単体テストは、依存関係をモックまたはシミュレートすることにより、残りのクラスから個々のクラスを分離することで機能します(可能な限り最小限に抑える必要があります)。静的クラスはいつでもアクセス可能であり、複数のテストに状態を伝えたり、テストが成功する前に初期化する必要があるため、責任があります。

  3. 依存関係を隠します。サービスプロバイダーのアンチパターン(XNA、Game.Servicesでも採用されている)と同様に、クラスでは外部には見られない依存関係を選択できます。

このアプローチは、静的クラスと貨物列車の呼び出しを組み合わせた場合に特に有毒になります(Game.Instance.ActorManager.Enemies.FindInRange(10)列車の車のようなチェーンシンボルのために、コンポーネントが突然Gameクラスを必要とするだけでなくInstanceActorManager持つプロパティEnemiesを持つオブジェクトを返すプロパティFindInRange()方法。

変更可能な静的クラスを書くために私が受け入れる唯一の言い訳は、まだ学習中であり、一貫して良いデザインを適用する能力がなく、悪い選択を見つけるための訓練された目がまだないことです。

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