2017-03-17 57 views
0

我正在製作一個遊戲,其中玩家角色可以獲得改變他們的角色在我的世界模型中的行爲或添加功能的特徵。例如,角色可能獲得改變跌落傷害計算方式的「羽毛」特徵,或者意味着玩家現在可以拾取之前僅僅是場景一部分的物品的「強壯」特徵。如何在運行時實現可變功能?

我一直在他們相關的類中編碼特徵,並在布爾變換時改變行爲,但隨着特徵列表的增長,它變得相當難以管理。必須有一個更具擴展性和解耦的方式來做到這一點。我想要的一種完美的場景是,我可以編程類變體,並以某種方式在運行時切換它們,同時保留上一個對象的上下文和引用,但是可以通過任何其他方式來適當地滿足要求波紋管是一個很好的答案。)

你將如何實現這樣的功能,在方法改變和新功能獲得並在運行時被刪除(請給出一個假設的例子)如果你不想做我的爲我工作,你將使用哪種編程模式來實現這種行爲?

P.S.:請隨時提出更好的標題。我吮吸那些。一旦找到更好的一個,我會編輯它。

+0

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

回答

1

你可以嘗試實行Decorator Pattern,這通常是用來行爲添加和刪除動態物體,在不改變原有對象的引用。維基百科頁面給你很好的解釋和例子。 無論如何,我會嘗試向您展示一個簡單的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 
    } 
} 

現在我們創建角色的一個子類,增加了「羽毛」特質。這個子類必須包含它,以便擴展類的字段來改變自己的行爲:

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 
    } 
} 

如果您要添加的「羽毛」特質,你必須創建一個新的對象是這樣的:

Character character = new Character(); 
int fallDamage = character.calculateFallDamage(); // returns 10 
character = new FeatherDecorator(character); 
int newFallDamage = character.calculateFallDamage(); // returns 5 

這樣做可以保留對象的原始引用,但同時你可以改變他的行爲。如果你有興趣除去裝修,你可以添加一個方法是這樣的:

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

這正是我想要的兩個警告,也許你也可以幫助我。我的第一個問題是,據我瞭解,我可以添加任意數量的特徵。例如,我可以添加羽毛特徵,然後添加強壯的特徵,它會起作用。但是,如果我想刪除一個特徵,我只能刪除最後添加的特徵。就像在一個堆棧中。 我看到的第二個問題是否存在對角色對象的單個引用。有沒有辦法一次更新所有引用? – 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)可能會更好。 –