首页 > 解决方案 > 如何在 Java 中创建某个类的“预制件”

问题描述

我有一个具有不同参数的机器人类maxHealthmaxShieldattack。我想为这个类制作不同的“预制件”:只是一个机器人,但上面的变量有一些特定的值。例如,一个Assault将是一个带有500 maxHealthand的机器人300 maxShield,一个攻击没有额外的功能/变量,只是机器人的一个。最简单的方法是做另一个这样的课程:

public class Assault extends Robot{
  public Assault(){
      super(Constants.ASSAULT_HEALTH,Constants.ASSAULT_SHIELD);
  }
}

或机器人的自定义构造函数:

    public Robot(String type) {
        switch (type) {
            case ("ASSAULT"):
                health = 500;
                shield = 300;
            case ("MACHINE GUN"):
                health = 1000;
                shield = 600;
            default: 
                health = 200;
                shield = 400;

        }
    }

或机器人内部的功能:

public void setAssault(){
   this.health = 500
   this.shield = 300
}

但我认为有更好的解决方案,感谢您的帮助!

[编辑] 所以在评论中你建议使用这样的factory类?

public class RobotFactory {
    public static Robot createAssault(int posX, int posY){
        return new Robot(posX, posY, 500, 300);
    }
}

标签: javaclass

解决方案


我建议Builder使用模式而不是Factory- 在我看来,这种方法可以让您更有效地支持您将例如向机器人添加额外属性或例如您想强制用户始终提供一些额外属性的情况。如果您将拥有静态方法,那么对象构造函数的每次更改都会导致所有工厂方法的更改,并且额外的输入将修改方法签名。如果您将“预制件”保留为构建器实例,您将只需要修改Builder实现或在您从用户那里获取输入的地方添加额外的逻辑

基本上我的建议是准备类似的东西

class RobotBuilder {
    private int health;
    private int shield;

    public RobotBuilder setHealth(int health) {
        this.health = health;
        return this;
    }

    // all other setters etc... 

    public Robot build() {
        return new Robot(this.health, this.shield);
    }
}

// ...

RobotBuilder assaultPrefab = new RobotBuilder().setHealth(500).setShield(300);

// create assault:
Robot assault = assaultPrefab.build();

// e.g. getting input from user:
int bonusShield = whatIsYourBonusShield();

assaultPrefab.setShield(assaultPrefab.getShield() + bonusShield); 

// notice that you are modifying just the specific instance of prefab object 
// in this place, if you would modify factory method you would change factory's API 
// or need to add additional method when there is bonus etc...

您可以“就地”创建这样的预制件或在某种提供者/单例/服务中定义它 - 恕我直言,这是解决此问题的非常灵活的方法


推荐阅读