4

(メソッドを介して)GameStateを使用する型があったと想像してください。GameContextprocess

abstract class GameState {
    public abstract void process(GameContext context);
}

GameContext には、Player、Shops など、ゲームに不可欠なものが含まれます。

状態は、必要なものにアクセスします。

class CombatState extends GameState {
    public void process(GameContext context) {
        Player player = context.getPlayer();

        if(player.isAlive()) {
            //...
        }
    }
}

ステートメントは次のplayer.isAlive()ように書き換えることができますcontext.getPlayer().isAlive()

私の質問

デメテルの法則は、オブジェクトは直接の親戚とのみ相互作用するべきであると述べています。これは原則違反であり、どのように解決されますか?

各状態を動的に処理するには、仮パラメータが可能なすべての状態で受け入れられる必要があります。これにより、オブジェクトに必要なものを厳密に渡すことが難しくなります。これが、各状態が「メイン ソース」から必要なものを取得する理由です。主な情報源は結束力が非常に低いと感じShopStateます。CombatState

4

2 に答える 2

5

状態はプロセスではなく、プロセスはプロセスです。戦うことはプロセスであり、生きていることは状態です。

の抽象的な名前を使用するprocessと、デメテルの法則を破る必要があります。

この例を見てください:

class CombatProcess extends GameProcess {
    public void hit(Player puncher, Player beaten) {
        if (beaten.getState().isAlive()) {
           Weapon oneWeapon = one.getCurrentWeapon();
               ...
        }
    }
}

CombatProcess のすべては可能な限り具体的です。

どのプレイヤーがどのプレイヤーと戦うかを分析することは、CombatProcess 自体の責任ではありません! CombatProcess を開始する前に、誰と戦うかを知る必要があります。

編集:

この回答のコメントに、次のように書きました。

Set、List、または Map に状態がある場合、状態をポリモーフィックに処理することはできません。

これは絶対に正しいです。Hook/Anchor-Patternは 1996 年のもので、今でも広く使用されており、Windows で栄光を放っています (いわゆるsystem-hooks )。残念ながら、いくつかの批評家のせいで、OOD のトップ 10 パターンに入ることができませんでした。この批評家の一人は:

...プロセスのすべての操作を論理的な独立したフックに抽象化し、その後それらを固定して適切に反復することは容易ではありません。

私の個人的な意見では、フック/アンカー パターンは 1996 年に革命的であり、将来的には CDI (例ではスプリング) との組み合わせで革命的となるでしょう。

ついに!次のように決定できます。

  1. デメテルの法則を破る。
  2. フック/アンカー パターンをドロップします。
  3. ここに説明されている回避策を書いてください。
于 2015-12-09T09:05:41.137 に答える