用于制作比萨饼的设计模式

时间:2015-09-26 16:14:17

标签: design-patterns

我想制作一个小应用程序,它会根据给定的输入返回给我披萨。 我想制作一个中等大小的披萨,不同的输入 1.喜欢白面团或棕色面团2.不同类型的奶酪配料,比如白色或棕色奶酪3.洋葱或番茄或蘑菇的不同配料

那么我们如何决定在这里选择哪种模式,Builder或Decorator? 我觉得我们可以先用构建模式制作披萨,然后我们可以使用装饰模式,根据我们选择的不同配料来装饰披萨。我在这个理解中是否正确? 据我所知,装饰器模式用于装饰任何已存在的对象。要创建此现有对象,我们首先使用构建器模式。

3 个答案:

答案 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);