趣解设计模式之《小王的披萨店续集》

〇、小故事

在《小王的披萨店》这篇文章中,我们介绍了小王开披萨店的故事,并且为了解决多种口味披萨的扩展问题,引出了简单工厂 和工厂方法模式。但是,故事仍在继续,**如果芝加哥的披萨店和纽约的披萨店,要求往披萨上面加的配料都不一样,那么如何可以规范多种类型披萨的创建呢?**如下图所示:

【Dough 】生面团
【Sauce 】调味汁
【Cheese 】干酪、奶酪
【Clams】蛤蜊

那么为了解决类似的问题,就可以采用我们今天要介绍的模式------抽象工厂模式 。它解决了的是同一类型下多个产品族 的创建。通过抽象工厂,组合了多种类型产品的创建(类似产品线)。

一、模式定义

抽象工厂模式 (Abstract Factory Pattern)

提供一个接口 ,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

二、模式类图

对于抽象工厂,将一系列产品 (配料类型,比如:Dough、Sauce、Cheese、Clams)统一到一起去创建 (即:PizzaIngredientFactory 的实现类:NYPizzaingredientFactory�和ChicagoPizzaingredientFactory�)。PizzaIngredientFactory 中的createDough()、createSauce()等方法,不关心底层配料如何实现,它只关系产品类型,不在意创建细节。具体类图,如下所示:

三、代码实现

奶酪�原料及实现类 :Cheese.java、MozzarellaCheese.java、ReggianoCheese.java

java 复制代码
/** 奶酪接口 **/
public interface Cheese {
    void description();
}

/** 莫泽雷勒干酪 **/
public class MozzarellaCheese implements Cheese {
    public void description() {
        System.out.println("MozzarellaCheese");
    }
}

/** 帕尔玛奶酪 **/
public class ReggianoCheese implements Cheese {
    public void description() {
        System.out.println("ReggianoCheese");
    }
}

蛤蜊�原料及实现类 :Clams.java、FreshClams.java、FrozenClams.java

java 复制代码
/** 蛤蜊接口 **/
public interface Clams {
    void description();
}

/** 新鲜蛤蜊 **/
public class FreshClams implements Clams{
    public void description() {
        System.out.println("FreshClams");
    }
}

/** 冷冻蛤蜊 **/
public class FrozenClams implements Clams{
    public void description() {
        System.out.println("FrozenClams");
    }
}

生面团�原料及实现类 :Dough.java、ThickCrustDough.java、ThinCrustDough.java

java 复制代码
/** 生面团接口 **/
public interface Dough {
    void description();
}

/** 厚的面包皮生面团 **/
public class ThickCrustDough implements Dough {
    public void description() {
        System.out.println("ThickCrustDough");
    }
}

/** 薄的面包皮生面团 **/
public class ThinCrustDough implements Dough {
    public void description() {
        System.out.println("ThinCrustDough");
    }
}

调味汁�原料及实现类 :Sauce�.java、MarinaraSauce�.java、PlumTomatoSauce�.java

java 复制代码
/** 调味汁接口 **/
public interface Sauce {
    void description();
}

/** 番茄酱调味汁 **/
public class MarinaraSauce implements Sauce {
    public void description() {
        System.out.println("MarinaraSauce");
    }
}

/** 梅子西红柿调味汁 **/
public class PlumTomatoSauce implements Sauce {
    public void description() {
        System.out.println("PlumTomatoSauce");
    }
}

披萨原料抽象工厂及实现类 :PizzaIngredientFactory.java�、NYPizzaingredientFactory�.java、ChicagoPizzaingredientFactory�.java

java 复制代码
/** 披萨原料抽象工厂 **/
public interface PizzaIngredientFactory {
    Dough createDough();
    Sauce createSauce();
    Cheese createCheese();
    Clams createClams();
}

/** 芝加哥原料工厂 **/
public class ChicagoPizzaingredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThinCrustDough(); // 薄的面包皮生面团 
    }
    public Sauce createSauce() {
        return new MarinaraSauce(); // 番茄酱调味汁
    }
    public Cheese createCheese() {
        return new ReggianoCheese(); // 帕尔玛奶酪
    }
    public Clams createClams() {
        return new FreshClams(); // 新鲜蛤蜊
    }
}

/** 纽约原料工厂 **/
public class NYPizzaingredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThickCrustDough(); // 厚的面包皮生面团
    }
    public Sauce createSauce() {
        return new PlumTomatoSauce(); // 梅子西红柿调味汁
    }
    public Cheese createCheese() {
        return new MozzarellaCheese(); // 莫泽雷勒干酪
    }
    public Clams createClams() {
        return new FrozenClams(); // 冷冻蛤蜊
    }
}

创建Pizza及实现类 :Pizza�.java

java 复制代码
/** 披萨抽象类 **/
public abstract class Pizza {
    protected String name;
    protected Dough dough; // 面团
    protected Sauce sauce; // 酱
    protected Cheese cheese; // 干酪
    protected Clams clams; // 蛤蜊
    protected PizzaIngredientFactory pizzaIngredientFactory;

    /** 准备原材料 */
    public abstract void prepare();

    public void bake() {
        System.out.println("pizzaIngredientFactory bake()");
    }

    public void cut() {
        System.out.println("pizzaIngredientFactory cut()");
    }

    public void box() {
        System.out.println("pizzaIngredientFactory box()");
    }
}

奶酪口味披萨 :CheesePizza.java

java 复制代码
/** 奶酪口味披萨 **/
public class CheesePizza extends Pizza {

    public CheesePizza(PizzaIngredientFactory pizzaIngredientFactory) {
        this.pizzaIngredientFactory = pizzaIngredientFactory;
    }

    public void prepare() {
        System.out.println("CheesePizza prepare()");
        dough = pizzaIngredientFactory.createDough();
        sauce = pizzaIngredientFactory.createSauce();
        cheese = pizzaIngredientFactory.createCheese();
    }
}

蛤蜊口味披萨 :ClamPizza.java

java 复制代码
/** 蛤蜊口味披萨 **/
public class ClamPizza extends Pizza {

    public ClamPizza(PizzaIngredientFactory pizzaIngredientFactory) {
        this.pizzaIngredientFactory = pizzaIngredientFactory;
    }

    public void prepare() {
        System.out.println("ClamPizza prepare()");
        dough = pizzaIngredientFactory.createDough();
        sauce = pizzaIngredientFactory.createSauce();
        cheese = pizzaIngredientFactory.createCheese();
        // 加入蛤蜊配料
        clams = pizzaIngredientFactory.createClams();
    }
}

意大利辣肉肠口味披萨 :PepperoniPizza�.java

java 复制代码
/**意大利辣肉肠口味披萨 **/
public class PepperoniPizza extends Pizza {

    public PepperoniPizza(PizzaIngredientFactory pizzaIngredientFactory) {
        this.pizzaIngredientFactory = pizzaIngredientFactory;
    }

    public void prepare() {
        System.out.println("PepperoniPizza prepare()");
        dough = pizzaIngredientFactory.createDough();
        sauce = pizzaIngredientFactory.createSauce();
        cheese = pizzaIngredientFactory.createCheese();
        // 加入蛤蜊配料
        clams = pizzaIngredientFactory.createClams();
    }
}

蔬菜口味披萨 :VeggiePizza�.java

java 复制代码
/** 蔬菜口味披萨 **/
public class VeggiePizza extends Pizza {

    public VeggiePizza(PizzaIngredientFactory pizzaIngredientFactory) {
        this.pizzaIngredientFactory = pizzaIngredientFactory;
    }

    public void prepare() {
        System.out.println("VeggiePizza prepare()");
        dough = pizzaIngredientFactory.createDough();
        sauce = pizzaIngredientFactory.createSauce();
        cheese = pizzaIngredientFactory.createCheese();
    }
}

披萨工厂及实现类 :PizzaStoreV3.java、NYPizzaStore.java

java 复制代码
public abstract class PizzaStoreV3 {
    protected abstract Pizza createPizza(String pizzaType);

    public Pizza orderPizza(String pizzaType) {
        Pizza pizza = createPizza(pizzaType);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

public class NYPizzaStore extends PizzaStoreV3 {
    protected Pizza createPizza(String pizzaType) {
        Pizza pizza = null;
        PizzaIngredientFactory pizzaIngredientFactory = new NYPizzaingredientFactory();
        if (pizzaType.equals("cheese")) {
            pizza = new CheesePizza(pizzaIngredientFactory);
        } else if (pizzaType.equals("pepperoni")) {
            pizza = new PepperoniPizza(pizzaIngredientFactory);
        } else if (pizzaType.equals("clam")) {
            pizza = new ClamPizza(pizzaIngredientFactory);
        } else if (pizzaType.equals("veggie")) {
            pizza = new VeggiePizza(pizzaIngredientFactory);
        }
        return pizza;
    }
}

抽象工厂测试类 :PizzaStoreTest.java

java 复制代码
public class PizzaStoreTest {
    public static void main(String[] args) {
        PizzaStoreV3 pizzaStore = new NYPizzaStore();
        pizzaStore.orderPizza("cheese");
    }
}

四、工厂方法和抽象工厂的区别

抽象工厂的方法经常以工厂方法的方式实现。也就是说,工厂方法经常会潜伏在抽象工厂里面。

工厂方法的特点:

【1 】采用继承 的方法实现。

【2 】通过抽象方法,来通过子类实现该方法,生成对象。

抽象工厂的特点:

【1 】采用组合 的方法实现。

【2 】通过提供接口,来创建一组产品的接口。这个接口内的每个方法都负责创建一个具体产品。

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
专业程序开发源1 小时前
springboot生命故事书制作小程序65290-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·mysql·小程序·课程设计
AINative软件工程1 小时前
LLM Prompt Registry 工程实践:集中管理 Prompt,让模型调用不再散落在代码各处
后端·python·llm
IT_陈寒2 小时前
SpringBoot自动配置的坑我帮你踩过了
前端·人工智能·后端
vx_Biye_Design2 小时前
springboot角色扮演服务平台65161-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
vx_Biye_Design2 小时前
springboot咖啡厅顾客点单管理系统12080-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
专业程序开发源2 小时前
flask动漫推荐系统32319-计算机课程设计、毕业设计
java·spring boot·后端·django·flask·php·课程设计
FYKJ_20102 小时前
springboot手工蜀绣在线销售系统60947-计算机课程设计、毕业设计
java·spring boot·后端·python·mysql·spark·课程设计
vx_Biye_Design2 小时前
springboot老年人用药智能管理系统38605-计算机课程设计、毕业设计
java·spring boot·后端·python·django·课程设计·express
苏离~Hack2 小时前
惠民云平台开发实战:基于 Vue3 + Django 的社区服务系统设计与实现
后端·python·django
明月_清风11 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端