如何在运行时实现可变功能?

时间:2017-03-17 22:08:50

标签: design-patterns polymorphism

我正在制作一个游戏,其中玩家角色可以获得改变角色在我的世界模型中的行为或添加功能的特征。例如,角色可能会获得羽毛"改变坠落伤害计算方式或强度"强度"特征意味着玩家现在可以拾取以前只是风景的一部分的物品。

我一直在对相关类中的特征进行硬编码,并在它们进入游戏时切换布尔值以改变行为,但随着我的特征列表的增长,它变得相当难以管理。必须有一种更具可扩展性和解耦方式的方法。

(我想要的完美场景是一种方法,我可以编写类变体并在运行时以某种方式切换它们,同时保留上一个对象的上下文和引用,但是任何其他方式可以适当地满足下面的要求是一个很好的答案。)

如何在运行时获取并删除新功能的情况下如何实现这样的功能?(请提供给定方案的假设示例)如果您不愿意为我工作,那么编程模式会你用来实现这种行为吗?

  

P.S。:请随意提出一个更好的头衔。我很沮丧。我会在找到更好的一个后编辑出来。

1 个答案:

答案 0 :(得分: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
    }
}

现在我们创建一个Character的子类,添加“羽毛”特征。此子类必须包含它为了更改其行为而扩展的类的字段:

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

通过这种方式,您可以保留对Object的原始引用,但同时您可以更改其行为。如果您有兴趣删除装饰,可以添加如下方法:

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

我希望我能帮到你,Decorator Pattern是一个非常强大的模式,它为对象的行为提供了一些灵活性。如果您需要更多解释,请与我们联系。