我想制作一个小应用程序,它会根据给定的输入返回给我披萨。 我想制作一个中等大小的披萨,不同的输入 1.喜欢白面团或棕色面团2.不同类型的奶酪配料,比如白色或棕色奶酪3.洋葱或番茄或蘑菇的不同配料
那么我们如何决定在这里选择哪种模式,Builder或Decorator? 我觉得我们可以先用构建模式制作披萨,然后我们可以使用装饰模式,根据我们选择的不同配料来装饰披萨。我在这个理解中是否正确? 据我所知,装饰器模式用于装饰任何已存在的对象。要创建此现有对象,我们首先使用构建器模式。
答案 0 :(得分:1)
所有示例都是用Java编写的
TLTR:向下滚动到Builder模式
例如,如果您有一个表示Rectangle的类,则会使用装饰器模式。 Rectangle类只有一个计算周长的方法。现在,您要向Rectangle添加一个方法来计算面积。问题是你不能也不想编辑Rectangle类,所以你创建一个新类MySuperDuperRectangle,如:
周边界面:
interface Perimeter{
public int perimeter();
}
由于某种原因我们无法改变的矩形
class Rectange implements perimeter{
private int a, b;
public Rectange(int a, int b){
this.a = a;
this.b = b;
}
public int getA(){
return a;
}
public int getB(){
return b;
}
public int perimeter(){
return 2 * a + 2 * b;
}
}
装饰矩形:
class MySuperDuperRectange implements perimeter{
private Rectange r;
public MySuperDuperRectange(Rectange r){
this.r = r;
}
public int perimeter(){
return r.perimeter();
}
public float area(){
return r.getA() * r.getB();
}
}
我会使用Builder模式,因为任务是building
披萨。
构建器模式用于构建后缀按原样存在的内容(并且不应随时更改)。
PizzaBuiler的基本实现可能如下所示:
Dough enum:
enum Dough{
WHITE, BROWN
}
Cheese enum:
enum Cheese{
WHITE, BROWN
}
Toppings枚举:
enum Topping{
Kittens, Onions, Salami
}
yummi Pizza:
class Pizza{
private Dough dough;
private Cheese cheese;
private HashSet<Topping> toppings;
private Pizza(Dough dough, Cheese cheese, HashSet<Topping> toppings){
this.dough = dough;
this.cheese = cheese;
this.toppings = toppings;
}
//add some getters
}
PizzaBuilder:
class PizzaBuilder{
private Dough dough;
private Cheese cheese;
private HashSet<Topping> toppings = new HashSet<Topping>();
public PizzaBuilder(){
}
public PizzaBuilder setDough(Dough dough){
this.dough = dough;
return this;
}
public PizzaBuilder setCheese(Cheese cheese){
this.cheese = cheese;
return this;
}
public PizzaBuilder addTopping(Topping topping){
this.toppings.add(topping);
return this;
}
public Pizza buildPizza(){
return new Pizza(this.dough, this.cheese, this.toppings);
}
}
现在我们要制作披萨:
Pizza myPizza = new PizzaBuilder()
.setDough(Dough.WHITE)
.setCheese(Cheese.WHITE)
.addTopping(Topping.Kittens)
.addTopping(Topping.Salami)
.buildPizza();
正如你所看到的那样,创造一个新的比萨饼非常紧张,并且不需要你为地球上每一个可能的披萨写一个新的课程;)
参考实施:Builder Pattern
答案 1 :(得分:0)
Creational Patterns不是你想要的:你只有一种类型的对象:Pizza。因此,Factory和Builder模式都不会这样做。
根据维基百科:
装饰器模式允许用户向其添加新功能 现有对象而不改变其结构。这种类型的设计 模式属于结构模式,因为这种模式充当了一种模式 包装到现有的类。
装饰者模式显然是你所需要的。
答案 2 :(得分:0)
您可以在构建披萨对象时继续使用Builder模式,传递面团,您选择的浇头,此处不需要装饰器模式:
Builder Pattern示例,如下所示:
package com.builder.pattern;
公共课程披萨{
boolean isCheesy;
boolean isTomato;
boolean isMaxican;
public Pizza(PizzaBuilder pizzaBuilder) {
this.isCheesy = pizzaBuilder.isCheesy;
this.isTomato = pizzaBuilder.isTomato;
this.isMaxican = pizzaBuilder.isMaxican;
}
static class PizzaBuilder {
boolean isCheesy;
boolean isTomato;
boolean isMaxican;
public Pizza build() {
return new Pizza(this);
}
public PizzaBuilder setCheese(boolean isCheesy) {
this.isCheesy = isCheesy;
return this;
}
public PizzaBuilder setTomato(boolean isTomato) {
this.isTomato = isTomato;
return this;
}
public PizzaBuilder setMaxican(boolean isMaxican) {
this.isMaxican = isMaxican;
return this;
}
}
@Override
public String toString() {
return "Pizza [isCheesy=" + isCheesy + ", isTomato=" + isTomato + ", isMaxican=" + isMaxican + "]";
}
}
准备披萨如下:
Pizza pizza = new Pizza.PizzaBuilder().setCheese(false).setTomato(true).setMaxican(true).build();
System.out.println(pizza);
或者像这样
Pizza pizza = new Pizza.PizzaBuilder().setMaxican(true).build();
System.out.println(pizza);