Java 具有抽象类的生成器模式

Java 具有抽象类的生成器模式,java,oop,builder-pattern,Java,Oop,Builder Pattern,我试图通过一个比萨饼的例子来学习和实现构建器模式 我正在尝试扩展解决方案,我还必须实现一件事: 用户应该能够订购特定的比萨饼(夏威夷、肉、蔬菜) )里面有一点定制。肉比萨饼中的-->示例 -->加入鸡肉+培根 寻找有关以更干净的方式实施此功能的建议(避免使用if-else) 这是我的披萨和披萨制作课程: public class Pizza { private String dough; private String sauce; private String toppings;

我试图通过一个比萨饼的例子来学习和实现构建器模式

我正在尝试扩展解决方案,我还必须实现一件事:

用户应该能够订购特定的比萨饼(夏威夷、肉、蔬菜) )里面有一点定制。肉比萨饼中的-->示例 -->加入鸡肉+培根

寻找有关以更干净的方式实施此功能的建议(避免使用if-else)

这是我的披萨和披萨制作课程:

public class Pizza {

  private String dough;
  private String sauce;
  private String toppings;

  public Pizza(PizzaBuilder pizzaBuilder) {
    this.dough = pizzaBuilder.dough;
    this.sauce = pizzaBuilder.sauce;
    this.toppings = pizzaBuilder.toppings;
  }

  public void setDough(String dough) {
    this.dough = dough;
  }

  public void setSauce(String sauce) {
    this.sauce = sauce;
  }

  public void setToppings(String toppings) {
    this.toppings = toppings;
  }

  abstract static class PizzaBuilder {
    private String dough;
    private String sauce;
    private String toppings;
    protected Pizza pizza;

    abstract void addDough();
    abstract void addSauce();
    abstract void addToppings();

    public PizzaBuilder addDough(String dough) {
      this.dough = dough;
      return this;
    }

    public PizzaBuilder addSauce(String sauce) {
      this.sauce = sauce;
      return this;
    }

    public PizzaBuilder addToppings(String toppings) {
      this.toppings = toppings;
      return this;
    }

    public Pizza bakeAPizza() {
      return pizza;
    }

    public PizzaBuilder makeAPizza() {
      getPizza();
      this.addDough();
      this.addSauce();
      this.addToppings();
      return this;
    }

    public PizzaBuilder getPizza() {
      pizza = new Pizza(this);
      return this;
    }
  }

  @Override
  public String toString() {
    return "Pizza{" + "dough='" + dough + '\'' + ", sauce='" + sauce + '\'' + ", toppings='" + toppings + '\'' + '}';
  }
}
public class MeatPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {
    pizza.setDough("Italian Wheat");
  }

  @Override
  void addSauce() {
    pizza.setSauce("mustard");
  }

  @Override
  void addToppings() {
    pizza.setToppings("Meat");
  }
}
   public class GenericPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {

  }

  @Override
  void addSauce() {

  }

  @Override
  void addToppings() {

  }
}
这是我的PizzaBuilder课程:

public class Pizza {

  private String dough;
  private String sauce;
  private String toppings;

  public Pizza(PizzaBuilder pizzaBuilder) {
    this.dough = pizzaBuilder.dough;
    this.sauce = pizzaBuilder.sauce;
    this.toppings = pizzaBuilder.toppings;
  }

  public void setDough(String dough) {
    this.dough = dough;
  }

  public void setSauce(String sauce) {
    this.sauce = sauce;
  }

  public void setToppings(String toppings) {
    this.toppings = toppings;
  }

  abstract static class PizzaBuilder {
    private String dough;
    private String sauce;
    private String toppings;
    protected Pizza pizza;

    abstract void addDough();
    abstract void addSauce();
    abstract void addToppings();

    public PizzaBuilder addDough(String dough) {
      this.dough = dough;
      return this;
    }

    public PizzaBuilder addSauce(String sauce) {
      this.sauce = sauce;
      return this;
    }

    public PizzaBuilder addToppings(String toppings) {
      this.toppings = toppings;
      return this;
    }

    public Pizza bakeAPizza() {
      return pizza;
    }

    public PizzaBuilder makeAPizza() {
      getPizza();
      this.addDough();
      this.addSauce();
      this.addToppings();
      return this;
    }

    public PizzaBuilder getPizza() {
      pizza = new Pizza(this);
      return this;
    }
  }

  @Override
  public String toString() {
    return "Pizza{" + "dough='" + dough + '\'' + ", sauce='" + sauce + '\'' + ", toppings='" + toppings + '\'' + '}';
  }
}
public class MeatPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {
    pizza.setDough("Italian Wheat");
  }

  @Override
  void addSauce() {
    pizza.setSauce("mustard");
  }

  @Override
  void addToppings() {
    pizza.setToppings("Meat");
  }
}
   public class GenericPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {

  }

  @Override
  void addSauce() {

  }

  @Override
  void addToppings() {

  }
}
类似于肉类比萨制造者:我有夏威夷比萨制造者、蔬菜比萨制造者和普通比萨制造者。以下是我的GenericPizzaBuilder类:

public class Pizza {

  private String dough;
  private String sauce;
  private String toppings;

  public Pizza(PizzaBuilder pizzaBuilder) {
    this.dough = pizzaBuilder.dough;
    this.sauce = pizzaBuilder.sauce;
    this.toppings = pizzaBuilder.toppings;
  }

  public void setDough(String dough) {
    this.dough = dough;
  }

  public void setSauce(String sauce) {
    this.sauce = sauce;
  }

  public void setToppings(String toppings) {
    this.toppings = toppings;
  }

  abstract static class PizzaBuilder {
    private String dough;
    private String sauce;
    private String toppings;
    protected Pizza pizza;

    abstract void addDough();
    abstract void addSauce();
    abstract void addToppings();

    public PizzaBuilder addDough(String dough) {
      this.dough = dough;
      return this;
    }

    public PizzaBuilder addSauce(String sauce) {
      this.sauce = sauce;
      return this;
    }

    public PizzaBuilder addToppings(String toppings) {
      this.toppings = toppings;
      return this;
    }

    public Pizza bakeAPizza() {
      return pizza;
    }

    public PizzaBuilder makeAPizza() {
      getPizza();
      this.addDough();
      this.addSauce();
      this.addToppings();
      return this;
    }

    public PizzaBuilder getPizza() {
      pizza = new Pizza(this);
      return this;
    }
  }

  @Override
  public String toString() {
    return "Pizza{" + "dough='" + dough + '\'' + ", sauce='" + sauce + '\'' + ", toppings='" + toppings + '\'' + '}';
  }
}
public class MeatPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {
    pizza.setDough("Italian Wheat");
  }

  @Override
  void addSauce() {
    pizza.setSauce("mustard");
  }

  @Override
  void addToppings() {
    pizza.setToppings("Meat");
  }
}
   public class GenericPizzaBuilder extends PizzaBuilder {

  @Override
  void addDough() {

  }

  @Override
  void addSauce() {

  }

  @Override
  void addToppings() {

  }
}
最后是比萨店(主要方法)

因此,用户应该能够说:

我想要一个鸡肉肉比萨饼


这不是一个真正的答案,但有几点。1) 您通常不会
扩展
一个
生成器
类来创建
对象
——例如
通用比萨饼
肉比萨饼
将改为
扩展比萨饼
。2) 从面向对象的角度来看,我不认为
MeatPizza
genericppizza
是不同的
Object
s,当您已经将
配料
存储为
Pizza
上的字段时。它们只是带有不同的
浇头
字段的
比萨饼
对象。@BeUndead感谢您提及
扩展生成器
部分。我应该给我的班级恰当地命名。它应该是
GenericPiizzaBuilder
| |
夏威夷Pizzabuilder
。我扩展
Builder
的唯一原因是,对于这些现成的PizzaBuilder,我不必设置任何参数。但是现在,我想给用户提供修改任何参数的功能。就像前面提到的@BeUndead一样,通过扩展
Builder
类来制作标准类型的比萨饼,你失去了Builder本身的价值。把建筑工人想象成厨师,把比萨饼的种类想象成食谱。当你有不同的食谱时,你不会雇佣新厨师,而是告诉厨师该做什么!代码中的配方是什么?子程序!如果你想有一个制作肉比萨饼的标准方法,只需要有一个方法
makeMeatPizza
,它用你想要的特定配置调用你的(通用)生成器。您添加的所有无参数方法都没有提供价值。在尝试并理解了
Builder模式
的工作原理后,我建议您检查
Lombok
可以为您做些什么。它可以为您生成方法和样板代码,这样您就可以摆脱实现,只关注程序的逻辑:)@BeUndead,扩展抽象构建器是如何在GoF书籍中定义模式的,因此在描述GoF模式的其他来源中也是如此(Pizza来自Head First Design)。在我看来,GoF模式是过度设计的,这就是为什么“您通常不
扩展
a
Builder
”。但从历史的角度来看,扩展抽象构建器是该模式的典型形式。今天常见的变化是改进。