DRY Java 代码的最佳方法是什么?为参数创建具有不同对象的私有方法?

Ili*_*Ili 0 java dry code-cleanup

我正在创建 RTS 游戏,其中一项功能是构建不同类型的建筑物。我发现了很多重复,我想在辅助方法中提取它,但问题是每个建筑物都是不同的对象,它们从主建筑物类中吸收了一些属性。

构建方法如下所示:

  public static void buildDockyard(Base base) {
    if (Validator.checkForBuilding(base, "Dockyard")) {
       throw new IllegalStateException("Dockyard is already build");
     }
    Dockyard dockyard = new Dockyard("Dockyard");
    int requiredPower = dockyard.requiredResource("power");
    int requiredStardust = dockyard.requiredResource("stardust");
    int requiredPopulation = dockyard.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    dockyard.setCompleteTime(dockyard.requiredResource("time"));
    base.getBuildings().add(dockyard);
  }

  public static void buildHotel(Base base) {
    if (Validator.checkForBuilding(base, "Space Hotel")) {
      throw new IllegalStateException("Space Hotel is already build");
    }

    SpaceHotel spaceHotel = new SpaceHotel("Space Hotel");
    int requiredPower = spaceHotel.requiredResource("power");
    int requiredStardust = spaceHotel.requiredResource("stardust");
    int requiredPopulation = spaceHotel.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    spaceHotel.setCompleteTime(spaceHotel.requiredResource("time"));
    base.getBuildings().add(spaceHotel);

    base.setCapacity(base.getCapacity() + spaceHotel.getCapacity());
  }
Run Code Online (Sandbox Code Playgroud)

我正在考虑这样重构:辅助方法

private static void construct(Building building, Base base) {
    int requiredPower = building.requiredResource("power");
    int requiredStardust = building.requiredResource("stardust");
    int requiredPopulation = building.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    building.setCompleteTime(building.requiredResource("time"));
  }
Run Code Online (Sandbox Code Playgroud)

目标结果

public static void buildDockyard(Base base) {
        if (Validator.checkForBuilding(base, "Dockyard")) {
           throw new IllegalStateException("Dockyard is already build");
         }
        Dockyard dockyard = new Dockyard("Dockyard");
        construct(dockyar, base);
        base.getBuildings().add(dockyard);
      }
Run Code Online (Sandbox Code Playgroud)

问题是每个建筑物都有独特的属性和资源需求,而主 Building 类不知道它们,所以我不能将其用作辅助方法中的参数。

所有这些都发生在 Base 类的静态帮助器类中。

你会如何重构这段代码?先感谢您 !

Tar*_*rmo 5

您的问题始于对所有内容使用静态方法。在面向对象的世界里,你最好有一个对象Base,它会具有非静态方法addStructure(Struture structure)Structure是例如一个接口。现在,您将拥有像BuildingDockyard将实现Structure.

的实现addStructure将是这样的:

if (getBuildings().contains(structure)) {
   throw new IllegalStateException(structure.name + " is already build");
}
if (validateStillHaveEnoughResourcesFor(structure)) {
   throw new IllegalStateException(structure.name + " can not be added. Not enough resources");
}
getBuildings().add(structure);
Run Code Online (Sandbox Code Playgroud)

验证结构本身不应该在基础上。验证结构如何适应底座应该在底座中。