有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java这是一种已建立的设计模式吗?

我正在用Java编写一个游戏,其中每个Entity可以有一个附加的EntityComponents列表。例如,可以被杀死的Entities(例如Player)将有一个Health组件。检查玩家的健康状况如下所示:

int health = ((Health) player.getComponent(Health.KEY)).getValue();

我想出了一个简单的快捷方式,其中每个EntityComponent都包含一个静态get方法,该方法使用适当的键调用实体的getComponent方法。现在检查玩家的健康状况如下所示:

int health = Health.of(player).getValue();

这是一个既定的设计模式吗?如果是,是哪一个?这看起来是一个好主意吗(本质上是为稍微短一点的代码添加了一个方法调用)?也许有更好的方法来实现我的目标吗

编辑

一些澄清,这里

  • Health包含getValuesetValuemodValueisDead等方法
  • Health.of(entity)只调用entity.getComponent(KEY),其中KEYHealth类中的一个字段
  • Health.ofHealth.getValue以前分别称为Health.getHealth.getHealth,但根据注释进行了更改
  • 不是每个Entity都可以被杀死——也就是说,不是每个Entity都可以被杀死 祝你健康。因此,将getHealth方法添加到每个Entity将 不工作
  • 包含getHealth方法的Killable接口也不可用 理想,因为这需要每个可杀死的Entity都 重复相同的健康相关代码
  • 因此,选择具有单独的Health组件是一种选择 仔细考虑一个,以便将所有共享代码提取到一个公共 地点
  • 从公共基类扩展,例如KillableEntity也是不可行的解决方案,因为Health是许多可能的组件之一,并且定义一个容纳所有可能组合的继承结构是不切实际的(甚至可能是不可能的)

共 (6) 个答案

  1. # 1 楼答案

    3节课不是更容易吗

    public abstract class Person {
    
    }
    public class Mortal extends Person {
        //int health; 
        //setHealth(); getHealth{}; modHealth{}; 
        //mortal(int health)
    }
    public class Immortal extends Person {}
    

    然后,简单地说

    Person mortalPlayer = new Mortal(100);
    mortalPlayer.getHealth();
    
  2. # 2 楼答案

    你可以直接做,不需要添加玩家。getComponent方法,如果在getComponent方法后面没有任何特定的原因

    int health = player.getHealth(Health.KEY);
    

    玩家是父实体,玩家有健康组件,所以getHealth方法应该在玩家对象上,而不是像这样

        int health = Health.get(player).getHealth();
    
  3. # 3 楼答案

    这是一个既定的设计模式吗?不,我更愿意把它描述为反模式

    int health = Health.get(player).getHealth();
    

    在这里,您要求健康获得玩家,然后要求玩家获得其健康,这可能会导致混乱

    据我所知,你似乎更喜欢构图而不是继承。考虑到这一点,像这样的事情可能更有意义

    int health = player.getComponentIntValue(Health.KEY);
    

    您也可以考虑让播放器实现HasHealthor接口,而不是将减少到:

    int health = player.getHealth();
    
  4. # 4 楼答案

    这不是一个答案,但我认为它将是有用的


    考虑使用^ {CD1>}方法提供对{{CD2>}:

    成员的直接访问
    public interface HealthComponent extends Health {
    
        Health healthComponent();
    
        default int currentHealth() {
            this.healthComponent().currentHealth();
        }
    }
    

    现在,如果Player实现了HealthHealthComponenthealthComponent方法,则可以执行以下操作:

    Player player = new Player();
    
    player.currentHealth();
    

    它要简洁得多。此模式模拟Scala的traits


    一些澄清:

    public interface Health {
    
        int currentHealth();
    
        void adjustHealth(int amount);
    
        boolean isDead();
    }
    
    
    public final class DefaultHealth implements Health {
    
        private int currentHealth;
    
        public DefaultHealth(final int startingHealth) {
    
            super();
    
            currentHealth = startingHealth;
        }
    
        public int currentHealth() {
    
            return currentHealth;
        }
    
        public void adjustHealth(final int amount) {
    
            if (isDead()) {
    
                return;
            }
    
            currentHealth += amount;
    
            if (currentHealth < 0) {
    
                currentHealth = 0;
            }
        }
    
        public boolean isDead() {
    
            return currentHealth > 0;
        }
    }
    
    public class Player implements HealthComponent {
    
        private final Health health;
    
        public Player(final Health health) {
    
            super();
    
            this.health = health;
        }
    
        public Health healthComponent() {
    
            return health;
        }
    }
    

    免责声明:此代码是在浏览器中编写的;它可能无法编译

  5. # 5 楼答案

    就像:

    get player's health, or get the health of the player

    我个人喜欢第一种方式。使用静态方法可能更好地用于具有原始参数且没有englobing上下文的方法(如过程范式中的函数,例如:Math.abs(int x)

    在你的情况下,健康是玩家的财产

  6. # 6 楼答案

    对于这个问题,我似乎只需要做一件以下的解决方案:

    1. 从实体派生播放器类,并为实体类实现getHealth()方法

    2. 使Entity成为需要getHealth()方法的接口,并在Player类中实现该方法,在本例中,该类实现Entity接口