这是在Java中实现装饰器或多重继承的新方法吗?
Is this a new way to implement Decorator or Multiple inheritance in Java?
我想知道我是否找到了另一种方法来实现 Java 中的装饰器设计模式?这可能是一种类似于 Java 中的多重继承的新方法吗?有没有更好的方法来实现下面的问题?
我针对以下问题提供了一个最小示例(图像是一个简单的游戏引擎):
Actor
: 是一个基本的actor,它有一个位置(在屏幕上)和一个可见性标志
- 一些 Actor 是
Damagable
,这意味着它们通过生命值、施加伤害的方法和必要时销毁它们(使基础 actor 不可见)的方法得到扩展。
- 一些 Actor 是
Physical
,这意味着它们可以施加重力等力,从而有效地改变基础 Actor 的位置。
- 有些Actor是
Damagable and Physical
,所以他们应该做一种多重继承或者应用2个装饰器(使用装饰器模式)。 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 的 Enemy,它有自己的方法并且也是 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();
}
}
}
你所做的是介于委托和组合之间的事情。在我看来,"Damageable" 和 "Physical" 应该独立运行并让 "EnemyActor" 委托给它们,而不是让接口委托给装饰器。我通过删除不必要的间接级别对其进行了一些清理。
编辑:我忘了说了。当您处理视频游戏时,有时性能优先。如果我们谈论的是由用户事件触发的操作,那么性能并不重要,但是如果我们谈论的是在循环中多次发生的操作——最好只让步并增加 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--;
}
}
我想知道我是否找到了另一种方法来实现 Java 中的装饰器设计模式?这可能是一种类似于 Java 中的多重继承的新方法吗?有没有更好的方法来实现下面的问题?
我针对以下问题提供了一个最小示例(图像是一个简单的游戏引擎):
Actor
: 是一个基本的actor,它有一个位置(在屏幕上)和一个可见性标志- 一些 Actor 是
Damagable
,这意味着它们通过生命值、施加伤害的方法和必要时销毁它们(使基础 actor 不可见)的方法得到扩展。 - 一些 Actor 是
Physical
,这意味着它们可以施加重力等力,从而有效地改变基础 Actor 的位置。 - 有些Actor是
Damagable and Physical
,所以他们应该做一种多重继承或者应用2个装饰器(使用装饰器模式)。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 的 Enemy,它有自己的方法并且也是 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();
}
}
}
你所做的是介于委托和组合之间的事情。在我看来,"Damageable" 和 "Physical" 应该独立运行并让 "EnemyActor" 委托给它们,而不是让接口委托给装饰器。我通过删除不必要的间接级别对其进行了一些清理。
编辑:我忘了说了。当您处理视频游戏时,有时性能优先。如果我们谈论的是由用户事件触发的操作,那么性能并不重要,但是如果我们谈论的是在循环中多次发生的操作——最好只让步并增加 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--;
}
}