我想知道我是否找到了另一种在Java中实现Decorator设计模式的方法?这可能是一种在Java中执行类似于多重继承的新方法吗?是否有更好的方法来实现下面的问题?
我提供了一个最小的例子,针对以下问题(图片简单的游戏引擎):
Actor
:是一个基本的演员,有一个位置(在屏幕上)和一个可见性标志Damagable
,这意味着他们可以通过健康点,施加伤害的方法以及摧毁它们(使基础角色隐形)进行扩展。Physical
,这意味着他们可以施加像重力一样的力量,这有效地改变了基础演员的位置。Damagable and Physical
,所以他们应该做一种多重继承或者应用2个Decorator(使用Decorator模式)。 EnemyActor
就是一个例子,当然还有自己的方法。这是我的实现(最小化):
public class Actor {
int posX;
int posY;
boolean visible = true;
}
public class DamagableActorDecoration {
float health = 10;
private final Actor base;
public DamagableActorDecoration(Actor base) {
this.base = base;
}
void applyDamage (float dmg) {
health -= dmg;
if (health<=0)
base.visible = false;
}
boolean isDestroyed () {
return health<=0;
}
}
public class PhysicalActorDecoration {
private final Actor base;
public PhysicalActorDecoration(Actor base) {
this.base = base;
}
public void applyGravity () {
base.posY--;
}
}
public interface Damagable {
DamagableActorDecoration d();
}
public interface Physical {
PhysicalActorDecoration p();
}
public class EnemyActor extends Actor implements Damagable, Physical{
@Override
public DamagableActorDecoration d() {
return new DamagableActorDecoration(this);
}
@Override
public PhysicalActorDecoration p() {
return new PhysicalActorDecoration(this);
}
public void showExplodingParticleSystem (){}
}
现在我可以创建一个扩展Actor的敌人,有自己的方法,也是Damagable和Physical。例如,通过这样使用它:
public class Runner {
public static void main(String[] args) {
EnemyActor enemy1 = new EnemyActor();
// basic actor behavior : appear
enemy1.visible=true;
// basic actor behavior : move forward
enemy1.posX++;
// damagable actor behavior : receive damage
enemy1.d().applyDamage(0.7f);
// physical actor behavior : fall down
enemy1.p().applyGravity();
// damagable actor behavior : be destroyed
if (enemy1.d().isDestroyed())
{
// enemy actor behavior : explode into pieces
enemy1.showExplodingParticleSystem();
}
}
}
答案 0 :(得分:1)
你所做的是代表团和作曲之间的事情。在我看来,&#34;可破坏&#34;和&#34;物理&#34;应该自己行动,并拥有&#34; EnemyActor&#34;委托给他们,而不是让接口委托给装饰者。我通过删除不必要的间接层来清理它。
编辑:我忘了提及。当您处理视频游戏时,有时性能优先。如果谈论的是由用户事件触发的操作,那么性能并不重要,但是如果我们谈论在循环中多次发生的操作 - 最好只是放弃和使用直接访问属性扩充Actor。public class EnemyActor extends Actor implements Damageable, Physical {
private final DamageableActorDecoration damageDecorator;
private final PhysicalActorDecoration physicalDecorator;
public EnemyActor() {
damageDecorator = new DamageableActorDecoration(this);
physicalDecorator = new PhysicalActorDecoration(this);
}
@Override
public void applyDamage(float dmg) {
damageDecorator.applyDamage(dmg);
}
@Override
public boolean isDestroyed() {
return damageDecorator.isDestroyed();
}
@Override
public void applyGravity() {
physicalDecorator.applyGravity();
}
}
public class Actor {
int posX;
int posY;
boolean visible = true;
}
public interface Damageable {
void applyDamage(float dmg);
boolean isDestroyed();
}
public class DamageableActorDecoration implements Damageable {
float health = 10;
private final Actor base;
public DamageableActorDecoration(Actor base) {
this.base = base;
}
@Override
void applyDamage(float dmg) {
health -= dmg;
if (health <= 0)
base.visible = false;
}
@Override
boolean isDestroyed() {
return health <= 0;
}
}
public interface Physical {
void applyGravity();
}
public class PhysicalActorDecoration implements Physical {
private final Actor base;
public PhysicalActorDecoration(Actor base) {
this.base = base;
}
@Override
public void applyGravity() {
base.posY--;
}
}