特定代码中的构建器与工厂设计模式

Builder vs Factory Design Pattern in specific code

我想问一下,在我的情况下,工厂或构建器设计模式哪个更好用。

长话短说,我有 class 个带有参数的操作:transferRate、recoverRate、cost 和 name。

在我的程序中,我将拥有包含 30 个(始终相同)Action 对象的数组。每个都有相同的参数设置。

我正在考虑更多关于使用工厂的问题,但如果您能给我建议哪个更好,我将不胜感激。

简短示例:

import lombok.Getter;

工厂:

@Getter
abstract public class Action {
    protected double transferRateBlock;
    protected double recoverRateBlock;
    protected int cost;
    protected String name;
}

public class CloseAirports extends Action {
    public CloseAirports(){
        this.transferRateBlock = -0.4;
        this.recoverRateBlock = 0;
        this.cost = 3;
        this.name = "Close airports";
    }
}

public class CloseBorders extends Action {
    public CloseBorders(){
        this.transferRateBlock = -0.5;
        this.recoverRateBlock = 0;
        this.cost = 4;
        this.name = "Close Borders";
    }
}

我有 30 个这样的子class。每个 subclass 都将排列在另一个 class 中。客户端只是使用这些操作,从不创建任何操作。每一个都是预先创建的。

CloseAirports closeAirports = new CloseAirports();
CloseBorders closeBorders = new CloseBorders();
Action[] allActions = {closeAirports, closeBorders};

或者我应该在此实现中使用构建器设计模式吗? :

Action closeSchool = new Action().withTransferRateBlock(0.5).withRecoverRateBlock(0).withCost(2).withName("Close Schools");
Action[] allActions = {closeSchool};

工厂示例:

public class ActionFactory implements AbstractFactory<Action>{

  @Override
  public Action createAction(int type) {
    switch(type) {
      case 1: return new CloseShops();
      case 2: return new CloseAirports();
      default: return null;
  }

}

因此,如果您想要区分类型,并避免让开发人员自己构建对象,这就是您要使用的。他仍然可以向 createAction 方法传递额外的参数。

List<Action> myActions = new ArrayList<>();
ActionFactory fact = new ActionFactory();
for ( int i = 0; i < 10; i++ ) {
  int type = assumeThisReadIntMethodExists();
  myActions.add(fact.createAction(type)); // this will add CloseShops or CloseAirports depending on the type passed
}

生成器示例: Builder模式更多的是为了避免在创建实例时出现问题。例如,缺少信息。

public class CloseShops {
  private final String nameOfShop;

  private CloseShops(String name) {
    this.nameOfShop = name; // as you can see, no check for null
    // it's always better to check for null before starting a constructor
  }

  public String getNameOfShop() {
    return nameOfShop;
  }
  // additional methods

  public static class Builder {
    private String name;

    public Builder withName(String name) {
      this.name = name;
      return this;
    }

    public Builder fromCloseShops(CloseShops original) {
      this.name = original.getNameOfShop();
      return this;
    }

    public CloseShops build() {
      assertNotNull("The name is mandatory", name);
      // this assert to avoid calling the constructor if the name is null
      return new CloseShops(this.name);
    }
}

可以这样调用:

Action b = new CloseShops.Builder().withName("shopName").build();

因此,如果要减少代码,请选择 Factory。