唐宋元明清 唐宋元明清
首页
  • 基础

    • Java基础
  • 工具

    • hutool
    • commons
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
  • Hadoop

    • Hadoop分布式搭建
    • Hadoop高可用搭建
    • 集群端口
    • 代码demo
  • Zookeeper

    • Zookeeper集群搭建
  • Hive

    • Hive集群搭建
    • Hive相关
    • HSQL
  • Kafka

    • Kafka集群搭建
  • HBase

    • HBase集群搭建
    • HBase基础学习
  • Spark

    • Spark环境搭建
    • Spark相关知识
  • Flink

    • Flink环境搭建
    • Flink学习
  • Flume

    • Flume安装配置
    • Flume高可用集群安装
    • Flume相关学习
  • Sqoop

    • Sqoop安装配置
    • Sqoop使用
  • 其他

    • docker
  • Oracle

    • Oracle相关知识杂记
    • 系统函数篇
    • 与MySQL语法区别
  • MySQL

    • MySQL知识点
  • Python

    • Python简单语法
    • Python操作Office
    • Python类库学习
    • Python爬虫
  • Shell

    • Shell基础
    • Shell命令行
  • Scala

    • 语法学习
  • 正则表达式

    • 正则基础
  • 调度

    • 调度工具
  • 前端

    • 前端相关
  • 杂记

    • 常用工具或网站
    • 琐碎知识
  • 摘录

    • 摘录
GitHub (opens new window)
首页
  • 基础

    • Java基础
  • 工具

    • hutool
    • commons
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
  • Hadoop

    • Hadoop分布式搭建
    • Hadoop高可用搭建
    • 集群端口
    • 代码demo
  • Zookeeper

    • Zookeeper集群搭建
  • Hive

    • Hive集群搭建
    • Hive相关
    • HSQL
  • Kafka

    • Kafka集群搭建
  • HBase

    • HBase集群搭建
    • HBase基础学习
  • Spark

    • Spark环境搭建
    • Spark相关知识
  • Flink

    • Flink环境搭建
    • Flink学习
  • Flume

    • Flume安装配置
    • Flume高可用集群安装
    • Flume相关学习
  • Sqoop

    • Sqoop安装配置
    • Sqoop使用
  • 其他

    • docker
  • Oracle

    • Oracle相关知识杂记
    • 系统函数篇
    • 与MySQL语法区别
  • MySQL

    • MySQL知识点
  • Python

    • Python简单语法
    • Python操作Office
    • Python类库学习
    • Python爬虫
  • Shell

    • Shell基础
    • Shell命令行
  • Scala

    • 语法学习
  • 正则表达式

    • 正则基础
  • 调度

    • 调度工具
  • 前端

    • 前端相关
  • 杂记

    • 常用工具或网站
    • 琐碎知识
  • 摘录

    • 摘录
GitHub (opens new window)
  • Java相关知识
  • 基础

    • Java基础
    • Java扩展
  • 工具

    • hutool工具包
    • Commons类库
    • SQL解析工具
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
    • 策略模式
    • 观察者模式
    • 装饰者模式
    • 工厂模式
      • 单例模式
      • 命令模式
      • 适配器模式与外观模式
      • 模板方法模式
      • 迭代器与组合模式
      • State 模式
      • 代理模式
    • Java相关
    • 设计模式
    Ai
    2022-07-16
    目录

    工厂模式

    # 三、工厂模式(Factory Pattern)

    # 问题提出

    当我们使用 "new" 来实例化对象时,也是在对具体实现编程。 比如我们根据条件的不同来实例化鸭子,需要编写以下代码

    Pizza orderPizza(String type) {
      Pizza pizza;
    
      if (type.equals("cheese")) {
        pizza = new CheesePizza();
      } else if (type.equals("clam")) {
        pizza = new ClamPizza();
      } else if (type.equals("veggie")) {
        pizza = new VeggiePizza();
      }
    
      pizza.perpare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      return pizza;
    }
    

    一旦发生修改或扩展,我们就必须去维护这段代码,容易出现问题(违反开闭原则)

    # 简单工厂

    简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。

    # 抽取变化的地方

    把创建不同对象这个 “变” 的地方抽取出来,不变的地方(其他方法)不做变动。

    public class SimplePizzaFactory {
      public Pizza createPizza(String type) {
        Pizza pizza;
    
        if (type.equals("cheese")) {
          pizza = new CheesePizza();
        } else if (type.equals("clam")) {
          pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
          pizza = new VeggiePizza();
        }
    
        return pizza;
      }
    }
    

    附:

    静态工厂:使用静态方法来定义简单工厂,可以不使用创建对象的方法来实例化对象。缺点是不能通过继承来修改创建方法内的行为。

    # 类图

    # 工厂方法模式

    工厂方法模式 定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

    # 开加盟店
    # 类图
    # 代码实现

      import java.util.ArrayList;
      
      public abstract class Pizza {
          protected String name;            // 披萨名字
          protected String dough;           // 面团类型
          protected String sauce;           // 酱料类型
          protected ArrayList topping= new ArrayList();     // 一套佐料
      
          public String getName() {
              return name;
          }
      
          public void perpare(){
              System.out.println("准备原料");
          }
          public void bake(){
              System.out.println("炙烤披萨");
          }
          public void cut(){
              System.out.println("披萨切片");
          }
          public void box(){
              System.out.println("披萨装盒");
          }
      }
      
      
      class ClamPizza extends Pizza {
          public ClamPizza() {
              name = "ClamPizza";
              System.out.println("初始化" + name);
          }
      }
      class VeggiePizza extends Pizza {
          public VeggiePizza() {
              name = "VeggiePizza";
              System.out.println("初始化" + name);
          }
      }
      class NYStyleCheesePizza extends Pizza {
          public NYStyleCheesePizza() {
              name = "NYStyleCheesePizza";
              System.out.println("初始化" + name);
          }
      }
      class ChicagoStyleCheesePizza extends Pizza {
          public ChicagoStyleCheesePizza() {
              name = "ChicagoStyleCheesePizza";
              System.out.println("初始化" + name);
          }
      
          @Override
          public void cut() {
              System.out.println("披萨切为方块");
          }
      }
      
      public abstract class PizzaStore {
          Pizza pizza = null;
      
          public Pizza orderPizza(String type) {
              return createPizza(type);
          }
      
          public void makePizza() {
              if (null != this.pizza) {
                  pizza.perpare();
                  pizza.bake();
                  pizza.cut();
                  pizza.box();
              }
          }
      
          protected abstract Pizza createPizza(String type);
      }
      
      class NYStylePizzaStore extends PizzaStore {
      
          @Override
          protected Pizza createPizza(String type) {
              if ("clam".equalsIgnoreCase(type)) {
                  pizza = new ClamPizza();
              } else if ("veggie".equalsIgnoreCase(type)) {
                  pizza = new VeggiePizza();
              } else if ("cheese".equalsIgnoreCase(type)) {
                  pizza = new NYStyleCheesePizza();
              }
              makePizza();
              return pizza;
          }
      }
      
      class ChicagoStylePizzaStore extends PizzaStore {
      
          @Override
          protected Pizza createPizza(String type) {
              if ("clam".equalsIgnoreCase(type)) {
                  pizza = new ClamPizza();
              } else if ("veggie".equalsIgnoreCase(type)) {
                  pizza = new VeggiePizza();
              } else if ("cheese".equalsIgnoreCase(type)) {
                  pizza = new ChicagoStyleCheesePizza();
              }
              makePizza();
              return pizza;
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              PizzaStore nyStylePizzaStore = new NYStylePizzaStore();
              PizzaStore chicagoStylePizzaStore = new ChicagoStylePizzaStore();
      
              Pizza nyCheese = nyStylePizzaStore.orderPizza("CHEESE");
              System.out.println(nyCheese.getName());
      
              Pizza chCheese = chicagoStylePizzaStore.orderPizza("CHEESE");
              System.out.println(chCheese.getName());
          }
      }
      
      // Make sure to add code blocks to your code group
      # 依赖倒置原则
      # 描述

      不能让高层组件依赖低层组件。而且,不管高层组件还是低层组件,都应该依赖于抽象。

      在应用工厂方法之后,你将注意到,高层组件(也就是PizzaStore)和低层组件(也就是这些比萨)都依赖了Pizz抽象。想要遵循依赖倒置原则,工厂方法并非是唯一的技巧,但却是最有威力的技巧之一。

      所谓倒置体现在:

      # 如何遵循此原则
      1. 变量不可以持有具体类的引用。
      2. 不要让类派生自具体类。
      3. 不要覆盖基类中已实现的方法

      # 抽象工厂模式

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

      # 原料工厂
      # 问题提出

      如何确保原料的一致?由于地域差别,每家店的披萨所使用的原材料并不完全一致。我们需要建造一个工厂生产原料,并处理各个区域的差异。

      # 类图

      抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样一来,客户就从具体的产品中被解耦。让我们看看类图来了解其中的关系:

      # 代码实现

        public interface Ingredient {}
        
        class Dough implements Ingredient {
            String name = "Dough";
            public Dough() {
                System.out.println("配料: " + name);
            }
        }
        class Sauce implements Ingredient {
            String name = "Sauce";
            public Sauce() {
            }
        }
        class Cheese implements Ingredient {
            String name = "Cheese";
            public Cheese() {
                System.out.println("配料: " + name);
            }
        }
        class Veggies implements Ingredient {
            String name = "Veggies";
        }
        class Carrot extends Veggies {
            public Carrot() {
                name = "胡萝卜";
                System.out.println("配料: " + name);
            }
        }
        class Lettuce extends Veggies {
            public Lettuce() {
                name = "生菜";
                System.out.println("配料: " + name);
            }
        }
        class Pepperoni implements Ingredient {
            String name = "Pepperoni";
            public Pepperoni() {
                System.out.println("配料: " + name);
            }
        }
        
        interface Clams extends Ingredient {}
        
        class FreshClams implements Clams {
            String name = "新鲜蛤蜊";
            public FreshClams() {
                System.out.println("配料: " + name);
            }
        }
        class FrozenClams implements Clams {
            String name = "冰冻蛤蜊";
            public FrozenClams() {
                System.out.println("配料: " + name);
            }
        }
        
        public interface PizzaIngredientFactory {
            Dough createDough();
            Sauce createSauce();
            Cheese createCheese();
            Veggies[] createVeggies();
            Pepperoni createPepperoni();
            Clams createClam();
        }
        
        
        class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
        
            @Override
            public Dough createDough() {
                return new Dough();
            }
        
            @Override
            public Sauce createSauce() {
                return new Sauce();
            }
        
            @Override
            public Cheese createCheese() {
                return new Cheese();
            }
        
            @Override
            public Veggies[] createVeggies() {
                return new Veggies[]{new Carrot(), new Lettuce()};
            }
        
            @Override
            public Pepperoni createPepperoni() {
                return new Pepperoni();
            }
        
            @Override
            public Clams createClam() {
                return new FreshClams();
            }
        }
        
        class NYPizzaIngredientFactory implements PizzaIngredientFactory {
        
            @Override
            public Dough createDough() {
                return new Dough();
            }
        
            @Override
            public Sauce createSauce() {
                return new Sauce();
            }
        
            @Override
            public Cheese createCheese() {
                return new Cheese();
            }
        
            @Override
            public Veggies[] createVeggies() {
                return new Veggies[]{new Lettuce()};
            }
        
            @Override
            public Pepperoni createPepperoni() {
                return new Pepperoni();
            }
        
            @Override
            public Clams createClam() {
                return new FrozenClams();
            }
        }
        
        public abstract class Pizza {
            protected String name;            // 披萨名字
            protected Dough dough;           // 面团类型
            protected Sauce sauce;           // 酱料类型
            protected List<Ingredient> topping= new ArrayList();     // 一套佐料
            protected Clams clams;
        
            public String getName() {
                return name;
            }
        
            public void perpare(){
                System.out.println("准备原料");
            }
            public void bake(){
                System.out.println("炙烤披萨");
            }
            public void cut(){
                System.out.println("披萨切片");
            }
            public void box(){
                System.out.println("披萨装盒");
            }
        }
        
        
        class ClamPizza extends Pizza {
            PizzaIngredientFactory pizzaIngredientFactory;   // 新增原料工厂
        
            public ClamPizza(PizzaIngredientFactory pizzaIngredientFactory) {
                name = "ClamPizza";
                this.pizzaIngredientFactory = pizzaIngredientFactory;
            }
        
            @Override
            public void perpare() {
                super.perpare();
                dough = pizzaIngredientFactory.createDough();
                sauce = pizzaIngredientFactory.createSauce();
                topping = Arrays.asList(pizzaIngredientFactory.createVeggies());
                clams = pizzaIngredientFactory.createClam();
            }
        }
        class VeggiePizza extends Pizza {
            public VeggiePizza() {
                name = "VeggiePizza";
                System.out.println("初始化" + name);
            }
        }
        class NYStyleCheesePizza extends Pizza {
            public NYStyleCheesePizza() {
                name = "NYStyleCheesePizza";
                System.out.println("初始化" + name);
            }
        }
        class ChicagoStyleCheesePizza extends Pizza {
            public ChicagoStyleCheesePizza() {
                name = "ChicagoStyleCheesePizza";
                System.out.println("初始化" + name);
            }
        
            @Override
            public void cut() {
                System.out.println("披萨切为方块");
            }
        }
        
        public abstract class PizzaStore {
            Pizza pizza = null;
            PizzaIngredientFactory pizzaIngredientFactory;   // 新增原料工厂
        
            public Pizza orderPizza(String type) {
                return createPizza(type);
            }
        
            public void makePizza() {
                if (null != this.pizza) {
                    pizza.perpare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }
            }
        
            protected abstract Pizza createPizza(String type);
        }
        
        class NYStylePizzaStore extends PizzaStore {
            public NYStylePizzaStore(PizzaIngredientFactory pizzaIngredientFactory) {
                super.pizzaIngredientFactory = pizzaIngredientFactory;
            }
        
            @Override
            protected Pizza createPizza(String type) {
                if ("clam".equalsIgnoreCase(type)) {
                    pizza = new ClamPizza(pizzaIngredientFactory);
                } else if ("veggie".equalsIgnoreCase(type)) {
                    pizza = new VeggiePizza();
                } else if ("cheese".equalsIgnoreCase(type)) {
                    pizza = new NYStyleCheesePizza();
                }
                makePizza();
                return pizza;
            }
        }
        
        class ChicagoStylePizzaStore extends PizzaStore {
            public ChicagoStylePizzaStore(PizzaIngredientFactory pizzaIngredientFactory) {
                super.pizzaIngredientFactory = pizzaIngredientFactory;
            }
        
            @Override
            protected Pizza createPizza(String type) {
                if ("clam".equalsIgnoreCase(type)) {
                    pizza = new ClamPizza(pizzaIngredientFactory);
                } else if ("veggie".equalsIgnoreCase(type)) {
                    pizza = new VeggiePizza();
                } else if ("cheese".equalsIgnoreCase(type)) {
                    pizza = new ChicagoStyleCheesePizza();
                }
                makePizza();
                return pizza;
            }
        }
        
        public class Main {
            public static void main(String[] args) {
                PizzaStore nyStylePizzaStore = new NYStylePizzaStore(new NYPizzaIngredientFactory());
                PizzaStore chicagoStylePizzaStore = new ChicagoStylePizzaStore(new ChicagoPizzaIngredientFactory());
        
                Pizza nyCheese = nyStylePizzaStore.orderPizza("Clam");
                System.out.println(nyCheese.getName());
        
                Pizza chCheese = chicagoStylePizzaStore.orderPizza("Clam");
                System.out.println(chCheese.getName());
            }
        }
        
        // Make sure to add code blocks to your code group

        # 要点

        抽象工厂的任务是定义创建一组产品的接口,这个接口里的每个方法都负责创建一个具体产品,同时我们通过实现抽象工厂子类来具体实现这些方法(工厂方法)。即,抽象工厂的方法通常是以工厂方法的方式实现的。

        • 所有的工厂都是用来封装对象的创建
        • 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解稠。
        • 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
        • 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
        • 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
        • 工厂方法允许类将实例化延迟到子类进行。
        • 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
        • 依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象。
        • 工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。
        编辑 (opens new window)
        上次更新: 2022/07/17, 00:24:40
        装饰者模式
        单例模式

        ← 装饰者模式 单例模式→

        Theme by Vdoing | Copyright © 2022-2025 Ai | MIT License
        • 跟随系统
        • 浅色模式
        • 深色模式
        • 阅读模式
        ×