Java 具有抽象类的生成器模式
我试图通过一个比萨饼的例子来学习和实现构建器模式 我正在尝试扩展解决方案,我还必须实现一件事: 用户应该能够订购特定的比萨饼(夏威夷、肉、蔬菜) )里面有一点定制。肉比萨饼中的-->示例 -->加入鸡肉+培根 寻找有关以更干净的方式实施此功能的建议(避免使用if-else) 这是我的披萨和披萨制作课程:Java 具有抽象类的生成器模式,java,oop,builder-pattern,Java,Oop,Builder Pattern,我试图通过一个比萨饼的例子来学习和实现构建器模式 我正在尝试扩展解决方案,我还必须实现一件事: 用户应该能够订购特定的比萨饼(夏威夷、肉、蔬菜) )里面有一点定制。肉比萨饼中的-->示例 -->加入鸡肉+培根 寻找有关以更干净的方式实施此功能的建议(避免使用if-else) 这是我的披萨和披萨制作课程: public class Pizza { private String dough; private String sauce; private String toppings;
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模式是过度设计的,这就是为什么“您通常不扩展aBuilder
”。但从历史的角度来看,扩展抽象构建器是该模式的典型形式。今天常见的变化是改进。