Строитель против Фабричного Проекта Паттерна в определенном c коде - PullRequest
0 голосов
/ 15 апреля 2020

Я хотел бы спросить, что лучше использовать, шаблон проектирования фабрики или сборщика, в моем случае.

Короче говоря, у меня есть класс Action с параметрами: 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 таких подклассов. Каждый подкласс собирается массив в другом классе. Клиент просто использует эти действия, а не создает их. Каждый всегда обрабатывается заранее.

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

Или я должен использовать скорее шаблон проектирования Builder с этой реализацией? :

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

1 Ответ

2 голосов
/ 15 апреля 2020

Пример фабрики:

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: шаблон 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();

Так что, если кода меньше, go для Фабрики.

...