2017-03-17 18 views
0

私は、プレイヤーキャラクターが私のワールドモデルでのキャラクターの振る舞いを変更したり、機能を追加したりする特性を得ることができるゲームを作っています。例えば、キャラクターは、墜落のダメージがどのように計算されるかを変更する「羽」の特性を得ることができ、以前は風景の一部であったアイテムをプレイヤーが選択できる「強い」特性を得ることができる。実行時に変更可能な機能を実装する方法は?

私は、関連するクラスの形質をハードにコーディングしていて、ブーリアンを切り替えることで動作が変わるようになりましたが、特性リストが成長するにつれて扱いにくくなってきています。これを行うには、よりスケーラブルでデカップルな方法が必要です。

(私が望む完璧なシナリオは、クラスバリエーションをプログラムして、実行時に、以前のオブジェクトのコンテキストと参照を維持しながら何らかの方法で切り替えられるようにする方法ですが、要件を適切に満たす他の方法

メソッドが変更され、新しい機能が実行時に取得され、削除されるようなこのような機能はどのように実装しますか?(特定のシナリオに仮定した例を示してください)あなたはこの種の行動を達成するためにどのプログラミングパターンを使用しますか?

P.S.:より良いタイトルを提案してください。私はそれらを吸う。私は良いものが見つかったらこれを編集します。

+0

https://sourcemaking.com/design_patterns/state – jaco0646

答えて

1

あなたは通常、元のオブジェクトの参照を変更せずに、動的にオブジェクトに振る舞いを追加および削除するために使用され、Decorator Patternを実装しようとすることができます。 Wikipediaのページには、良い説明と例があります。 とにかく、私は単純なJava(あなたが理解することを望んで、あなたは言語を指定していないことを望みます)を試してみます。 は、このような文字クラスがあるとします。

public class Character { 

    public int calculateFallDamage() { 
     return 10; 
    } 

    public void pickUpItem() { 
    // initially this method could be empty 
    // nothing happens when you try to pick up items 
    } 
} 

今、私たちは「羽」形質を追加文字のサブクラスを作成します。

Character character = new Character(); 
int fallDamage = character.calculateFallDamage(); // returns 10 
character = new FeatherDecorator(character); 
int newFallDamage = character.calculateFallDamage(); // returns 5 
:あなたはこのような新しいオブジェクトを作成する必要があり、「羽」形質を追加したい場合は

public class FeatherDecorator extends Character { 

    private Character decoratedCharacter; 

    public FeatherDecorator(Character character) { 
     this.decoratedCharacter = character; 
    } 

    @Override 
    public int calculateFallDamage() { 
     int fallDamage = decoratedCharacter.calculateFallDamage(); // call the function of the decorated class 
     return fallDamage - 5; // change the result 
    } 
} 

:このサブクラスは、その振る舞いを変更することが順番に拡張したクラスのフィールドが含まれている必要があります

このようにすると、オブジェクトへの元の参照を保持できますが、同時に彼の振る舞いを変更することができます。あなたは装飾を削除するに興味を持っている場合は、次のようにメソッドを追加することができます。

public class Character() { 
    ... 
    public Character getDecoratedComponent() { 
    // exception becaus it's not decorated 
    } 
    ... 
} 

public class FeatherDecorator extends Character { 

    private Character decoratedCharacter; 
    ... 
    @Override 
    public Character getDecoratedComponent() { 
     return decoratedCharacter; 
    } 
    ... 
} 

は、今では装飾なしで、元のオブジェクトを取得するのは非常に簡単です:

Character character = new FeatherDecorator(new Character()); 
character = character.getDecoratedComponent(); // returns the object without the feater decorator 

私は、私はあなたを助けている願って、デコレータパターンは、オブジェクトの振る舞いにいくらか柔軟性を与える非常に強力なパターンです。詳しい説明が必要な場合はお知らせください。

+0

これはまさに私が2つの注意書きで欲しいものです。多分それらも私に助けてくれるでしょう。私の最初の問題は、理解できる限り、任意の数の特性を追加できることです。たとえば、私は羽根の特性を追加して、強力な特性を追加することができ、それは機能します。しかし、私が特性を取り除きたいのであれば、最後に加えたものだけを取り除くことができます。スタックのように。 文字オブジェクトへの単一の参照が存在すると仮定すると、2番目の問題が発生します。一度にすべての参照を更新する方法はありますか? – Althis

+0

特定の装飾を削除する場合は、[この質問]を見ることができます(http://stackoverflow.com/questions/12239784/how-to-remove-decorated-object-from-decorator-pattern-in-java# 12240581)。申し訳ありませんが、同じオブジェクトに対してさまざまな参照があることを理解できませんでした。この事実はデコレータパターンに問題を引き起こす可能性があります。この場合、コメントに_jaco0646_が記載されているように、[State Pattern](https://sourcemaking.com/design_patterns/state)のほうが良いかもしれません。 –

関連する問題