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


    〇、小故事

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

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

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

    一、模式定义

    抽象工厂模式Abstract Factory Pattern

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

    二、模式类图

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

    三、代码实现

    奶酪原料及实现类Cheese.javaMozzarellaCheese.javaReggianoCheese.java

    1. /** 奶酪接口 **/
    2. public interface Cheese {
    3.     void description();
    4. }
    5. /** 莫泽雷勒干酪 **/
    6. public class MozzarellaCheese implements Cheese {
    7.     public void description() {
    8.         System.out.println("MozzarellaCheese");
    9.     }
    10. }
    11. /** 帕尔玛奶酪 **/
    12. public class ReggianoCheese implements Cheese {
    13.     public void description() {
    14.         System.out.println("ReggianoCheese");
    15.     }
    16. }

    蛤蜊原料及实现类Clams.javaFreshClams.javaFrozenClams.java

    1. /** 蛤蜊接口 **/
    2. public interface Clams {
    3.     void description();
    4. }
    5. /** 新鲜蛤蜊 **/
    6. public class FreshClams implements Clams{
    7.     public void description() {
    8.         System.out.println("FreshClams");
    9.     }
    10. }
    11. /** 冷冻蛤蜊 **/
    12. public class FrozenClams implements Clams{
    13.     public void description() {
    14.         System.out.println("FrozenClams");
    15.     }
    16. }

    生面团原料及实现类Dough.javaThickCrustDough.javaThinCrustDough.java

    1. /** 生面团接口 **/
    2. public interface Dough {
    3.     void description();
    4. }
    5. /** 厚的面包皮生面团 **/
    6. public class ThickCrustDough implements Dough {
    7.     public void description() {
    8.         System.out.println("ThickCrustDough");
    9.     }
    10. }
    11. /** 薄的面包皮生面团 **/
    12. public class ThinCrustDough implements Dough {
    13.     public void description() {
    14.         System.out.println("ThinCrustDough");
    15.     }
    16. }

    调味汁原料及实现类Sauce.javaMarinaraSauce.javaPlumTomatoSauce.java

    1. /** 调味汁接口 **/
    2. public interface Sauce {
    3.     void description();
    4. }
    5. /** 番茄酱调味汁 **/
    6. public class MarinaraSauce implements Sauce {
    7.     public void description() {
    8.         System.out.println("MarinaraSauce");
    9.     }
    10. }
    11. /** 梅子西红柿调味汁 **/
    12. public class PlumTomatoSauce implements Sauce {
    13.     public void description() {
    14.         System.out.println("PlumTomatoSauce");
    15.     }
    16. }

    披萨原料抽象工厂及实现类PizzaIngredientFactory.javaNYPizzaingredientFactory.javaChicagoPizzaingredientFactory.java

    1. /** 披萨原料抽象工厂 **/
    2. public interface PizzaIngredientFactory {
    3.     Dough createDough();
    4.     Sauce createSauce();
    5.     Cheese createCheese();
    6.     Clams createClams();
    7. }
    8. /** 芝加哥原料工厂 **/
    9. public class ChicagoPizzaingredientFactory implements PizzaIngredientFactory {
    10.     public Dough createDough() {
    11.         return new ThinCrustDough(); // 薄的面包皮生面团 
    12.     }
    13.     public Sauce createSauce() {
    14.         return new MarinaraSauce(); // 番茄酱调味汁
    15.     }
    16.     public Cheese createCheese() {
    17.         return new ReggianoCheese(); // 帕尔玛奶酪
    18.     }
    19.     public Clams createClams() {
    20.         return new FreshClams(); // 新鲜蛤蜊
    21.     }
    22. }
    23. /** 纽约原料工厂 **/
    24. public class NYPizzaingredientFactory implements PizzaIngredientFactory {
    25.     public Dough createDough() {
    26.         return new ThickCrustDough(); // 厚的面包皮生面团
    27.     }
    28.     public Sauce createSauce() {
    29.         return new PlumTomatoSauce(); // 梅子西红柿调味汁
    30.     }
    31.     public Cheese createCheese() {
    32.         return new MozzarellaCheese(); // 莫泽雷勒干酪
    33.     }
    34.     public Clams createClams() {
    35.         return new FrozenClams(); // 冷冻蛤蜊
    36.     }
    37. }

    创建Pizza及实现类Pizza.java

    1. /** 披萨抽象类 **/
    2. public abstract class Pizza {
    3.     protected String name;
    4.     protected Dough dough; // 面团
    5.     protected Sauce sauce; // 酱
    6.     protected Cheese cheese; // 干酪
    7.     protected Clams clams; // 蛤蜊
    8.     protected PizzaIngredientFactory pizzaIngredientFactory;
    9.     /** 准备原材料 */
    10.     public abstract void prepare();
    11.     public void bake() {
    12.         System.out.println("pizzaIngredientFactory bake()");
    13.     }
    14.     public void cut() {
    15.         System.out.println("pizzaIngredientFactory cut()");
    16.     }
    17.     public void box() {
    18.         System.out.println("pizzaIngredientFactory box()");
    19.     }
    20. }

    奶酪口味披萨CheesePizza.java

    1. /** 奶酪口味披萨 **/
    2. public class CheesePizza extends Pizza {
    3.     public CheesePizza(PizzaIngredientFactory pizzaIngredientFactory) {
    4.         this.pizzaIngredientFactory = pizzaIngredientFactory;
    5.     }
    6.     public void prepare() {
    7.         System.out.println("CheesePizza prepare()");
    8.         dough = pizzaIngredientFactory.createDough();
    9.         sauce = pizzaIngredientFactory.createSauce();
    10.         cheese = pizzaIngredientFactory.createCheese();
    11.     }
    12. }

    蛤蜊口味披萨ClamPizza.java

    1. /** 蛤蜊口味披萨 **/
    2. public class ClamPizza extends Pizza {
    3.     public ClamPizza(PizzaIngredientFactory pizzaIngredientFactory) {
    4.         this.pizzaIngredientFactory = pizzaIngredientFactory;
    5.     }
    6.     public void prepare() {
    7.         System.out.println("ClamPizza prepare()");
    8.         dough = pizzaIngredientFactory.createDough();
    9.         sauce = pizzaIngredientFactory.createSauce();
    10.         cheese = pizzaIngredientFactory.createCheese();
    11.         // 加入蛤蜊配料
    12.         clams = pizzaIngredientFactory.createClams();
    13.     }
    14. }

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

    1. /**意大利辣肉肠口味披萨 **/
    2. public class PepperoniPizza extends Pizza {
    3.     public PepperoniPizza(PizzaIngredientFactory pizzaIngredientFactory) {
    4.         this.pizzaIngredientFactory = pizzaIngredientFactory;
    5.     }
    6.     public void prepare() {
    7.         System.out.println("PepperoniPizza prepare()");
    8.         dough = pizzaIngredientFactory.createDough();
    9.         sauce = pizzaIngredientFactory.createSauce();
    10.         cheese = pizzaIngredientFactory.createCheese();
    11.         // 加入蛤蜊配料
    12.         clams = pizzaIngredientFactory.createClams();
    13.     }
    14. }

    蔬菜口味披萨VeggiePizza.java

    1. /** 蔬菜口味披萨 **/
    2. public class VeggiePizza extends Pizza {
    3.     public VeggiePizza(PizzaIngredientFactory pizzaIngredientFactory) {
    4.         this.pizzaIngredientFactory = pizzaIngredientFactory;
    5.     }
    6.     public void prepare() {
    7.         System.out.println("VeggiePizza prepare()");
    8.         dough = pizzaIngredientFactory.createDough();
    9.         sauce = pizzaIngredientFactory.createSauce();
    10.         cheese = pizzaIngredientFactory.createCheese();
    11.     }
    12. }

    披萨工厂及实现类PizzaStoreV3.javaNYPizzaStore.java

    1. public abstract class PizzaStoreV3 {
    2.     protected abstract Pizza createPizza(String pizzaType);
    3.     public Pizza orderPizza(String pizzaType) {
    4.         Pizza pizza = createPizza(pizzaType);
    5.         pizza.prepare();
    6.         pizza.bake();
    7.         pizza.cut();
    8.         pizza.box();
    9.         return pizza;
    10.     }
    11. }
    12. public class NYPizzaStore extends PizzaStoreV3 {
    13.     protected Pizza createPizza(String pizzaType) {
    14.         Pizza pizza = null;
    15.         PizzaIngredientFactory pizzaIngredientFactory = new NYPizzaingredientFactory();
    16.         if (pizzaType.equals("cheese")) {
    17.             pizza = new CheesePizza(pizzaIngredientFactory);
    18.         } else if (pizzaType.equals("pepperoni")) {
    19.             pizza = new PepperoniPizza(pizzaIngredientFactory);
    20.         } else if (pizzaType.equals("clam")) {
    21.             pizza = new ClamPizza(pizzaIngredientFactory);
    22.         } else if (pizzaType.equals("veggie")) {
    23.             pizza = new VeggiePizza(pizzaIngredientFactory);
    24.         }
    25.         return pizza;
    26.     }
    27. }

    抽象工厂测试类PizzaStoreTest.java

    1. public class PizzaStoreTest {
    2.     public static void main(String[] args) {
    3.         PizzaStoreV3 pizzaStore = new NYPizzaStore();
    4.         pizzaStore.orderPizza("cheese");
    5.     }
    6. }

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

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

    工厂方法的特点

    1】采用继承的方法实现。
    2】通过抽象方法,来通过子类实现该方法,生成对象。

    抽象工厂的特点

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

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

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

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

  • 相关阅读:
    Linux云服务器:MySQL安装失败、多种错误总结 | 个人解决参考
    【Linux多线程服务端编程】| 【05】高效的多线程日志
    【UNR #6 E】神隐(交互)(二进制分组)
    Flutter笔记:build方法、构建上下文BuildContext解析
    C语言初学习——易错点合集(持续更新中)
    SQlserver提权方法
    评论情感分析----多种机器学习模型测试总结
    基于灰狼算法GWO优化BP神经网络实现温度数据预测算法研究附matlab代码
    浅谈C++重载、重写、重定义
    [nodemon] app crashed - waiting for file changes before starting...解决方法
  • 原文地址:https://blog.csdn.net/qq_26470817/article/details/133428501