我在理解装饰设计模式时遇到了问题。让我们说我想在我的项目中使用它。这是一个平台游戏,所以我立即认为最好的用法是在敌人的课程。我希望有不同类型的敌人,基本的和其他的将是第一个的扩展(例如具有不同的属性,颜色,额外的AI逻辑)。根据我的理解,这是类应该是什么样子
abstract class Enemy{
float speedX,speedY;
int x,y,width,height;
COLOR colour;
Sprite sprite;
void setAnimation();
void update();
void render();
void init();
}
class EnemyBasic extends Enemy{
EnemyBasic() {
init();
}
void init() {
//set all variables
}
@Override
void setAnimation() {
//set animation
}
@Override
public void update() {
//update
}
@Override
public void render() {
render(sprite,colour,x,y,width,height)
}
}
class FastEnemy extends Enemy{
Enemy basicEnemy;
FastEnemy(Enemy basicEnemy) {
this.basicEnemy = basicEnemy;
init();
}
void init() {
basicEnemy.init();
maximalSpeed = basicEnemy.maximalSpeed*2;
}
@Override
void setAnimation() {
basicEnemy.setAnimation();
}
@Override
public void update() {
basicEnemy.update();
additionalMovementLogic();
}
additionalMovementLogic(){
}
@Override
public void render() {
color=green;
basicEnemy.render()
}
}
问题是,这不会起作用,因为来自basicEnemy
对象的方法调用将对EnemyBasic字段进行操作,而不是来自EnemyFast的那些字段。例如,render()将呈现EnemyBasic对象而不是EnemyFast。只有我能看到的解决方案是重新实现整个类,但是装饰类的重点是什么呢?我理解错了吗?或者在这种情况下装饰器不应该使用?如果是这样的话应该使用
答案 0 :(得分:1)
在目前的形式中,这看起来不像是Decorator Pattern的一个很好的用例,因为它需要改变basicEnemy的内部行为。我可以想到以下解决方案:
这种渲染器可以获得修饰值,例如:
答案 1 :(得分:0)
这实际上不是装饰器模式的实现 - 它只是子类化。您可以将装饰模式用于您的目的,但我建议您查看实体组件系统:
https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system
这是一种广泛用于游戏开发的设计模式,用于解决您尝试解决的各种问题。查看上面的文章和最后的外部链接。
答案 2 :(得分:0)
您可以通过 装饰器模式 进行正确的跟踪。但你必须要小心,你真正的要求是什么。
从你的代码中,我希望你会尝试这样的东西;
Enemy enemy = new EnemyFast(new EnemyBasic());
只有当 EnemyFast类行为= EnemyBasic类行为+一些添加时,这才有意义。
例如,在render()
内部的EnemyFast
方法中,类应该如下所示(与其他多态方法相同)。
注意 :类EnemyFast中的字段名称应从basicEnemy
更改为enemy
。从这个意义上说,这听起来更通用。
@Override
public void render() {
enemy.render(); //renderlogic of basic enemy
//implement additional logic you want, so that it would fill upto EnemyFast
}
因此,对于您的上一个问题,Decorator模式是一个概述对象演变的解决方案。相反,过于严格不采用纯粹的继承,Decorator模式告诉我们封装进化方法并使用组合重用它们,这为我们提供了更大的灵活性。如果我们仅通过继承(使用继承层次结构进行下调)来实现这一点,那么稍后出现的一些子类将必须继承其父类的所有方法(根本不需要)(这就是继承的原因)是一种太僵硬的方式)。所以 装饰器模式 也是使用composition over inheritance(合成/聚合)的完美示例。