7

クラス A がクラス B、C、および D のそれぞれと固有の相互作用を持つ場合、相互作用のコードは A にあるべきか、B、C、および D にあるべきか?

多くのオブジェクトが他のオブジェクトと独自の相互作用を持つことができる小さなゲームを書いています。たとえば、EMPa は a にヒットし、sentry gunそれを無効にします。また、 を攻撃しgrenadeて爆発させたり、 を攻撃playerして減速効果を適用したりすることもできます。

私の質問は、このコードを EMP クラスに入れるか、それとも他のすべてのクラスに分散させるべきかということです。私の直感は、これをポリモーフィックに行うように指示するので、各クラスに EMP ストライクを好きなように処理するように指示するだけです。これにより、EMP コードを変更せずに項目を追加し、EMP の処理方法を変更することができます。

ただし、EMP は現在、50 個のオブジェクトのうち約 4 個としかやり取りできないため、空の RespondToEMP() 呼び出しで 46 個のオブジェクトを満たすのは間違っているようです。EMP を削除することにした場合、他のすべてのクラスを変更する必要があり、EMP クラス自体がかなり小さくなってしまいます。また、EMP の動作を変更したい場合は、さまざまなクラスをすべて調べて、考えられるすべての用途を見つける必要があることも意味します。さらに、EMP に爆発などの一般的な効果がある場合、この効果は間違いなく EMP コード内にあり、配布される他のすべての効果から離れています。

4

5 に答える 5

1

http://en.wikipedia.org/wiki/Visitor_patternを検討することをお勧めします。2つ以上の相互作用がある場合は、オブジェクト間の関係の管理に対する私の答えを見てください。

于 2013-03-06T22:09:16.617 に答える
1

私の考えはそれsentry gungrenadeありplayer、メソッドを強制する共通のインターフェースをすべて実装する必要がありますRespondToEMP。このようにして、後で他の 46 個のオブジェクトの 1 つが EMP にヒットする可能性があると判断した場合、このインターフェイスを実装する必要があることがわかります。

于 2013-03-06T17:24:18.233 に答える
1

おっしゃる通り、ダミーのメソッドを持つことはコードの匂いです。これを回避するには、いくつかの方法があります。

オブジェクトを追加するときにイベントを変更する必要がなくなるため、オブジェクトを追加することが予想される場合は、イベントを処理するための switch ステートメントが適切に機能します。

enum Event { EMP, Bomb }

class SentryGun {
    void handleEvent(Event e) { switch(e) {
        case EMP: disable();
    }}
    void disable() {}
}
class Grenade {
    void handleEvent(Event e) { switch(e) {
            case EMP: detonate();
    }}
    void detonate() {}
}

オブジェクトを訪問するイベントは、そのイベントに反応できるようになったすべてのオブジェクトを変更する必要がないため、さらにイベントを追加することが予想される場合にうまく機能します。

class EMP {
    void hit(SentryGun object) {
        object.disable();
    }

    void hit(Grenade object) {
        object.detonate();
    }
}
于 2013-03-06T23:17:45.587 に答える
0

これは最も洗練された解決策ではありませんが、できることの 1 つは、イベントのデフォルトの動作を持つオブジェクトを拡張する基本クラスを用意することです。何かする必要がある場合、オブジェクトはそれをオーバーライドできます。

于 2013-03-06T21:53:12.073 に答える
0

あなたの場合、ある時点で、相互作用できるオブジェクトとできないオブジェクトを区別する必要があります。次の 3 つのオプションがあります。

  • 実装が空の可能性がある共通インターフェース
  • インターフェイスと、オブジェクトがそれを実装しているかどうかのチェック
  • インタラクションとリアクションを含むマップ/テーブルを定義する

最初の2つは他の回答で提示されたので、3番目のオプションについて説明します。マッピングを定義します: Thing x Object -> Command. この場合、EMP_hit は Thing (名前の方が良いかもしれません..) であり、そのソースに関する情報が含まれている可能性があります。オブジェクトはすべてあなたのものになります。コマンドはコマンド パターンに似ています ( http://en.wikipedia.org/wiki/Command_patternを参照)。これをテーブルではなくマップに保存して、空でないコマンドのみを保持し、同じクラスのモノ/オブジェクト間で共有されるいくつかの文字列 ID を使用して、このマッピングで適切なエントリを見つけます。

このソリューションには、構成ファイルで定義したり、実行時に動的に変更したりできるという利点があります。構成を変更するために再コンパイルは必要ありません

于 2013-03-06T23:51:43.897 に答える