• 工厂设计模式


    工厂设计模式的定义(what)

    参考:

    https://www.runoob.com/design-pattern/factory-pattern.html

    https://www.runoob.com/design-pattern/abstract-factory-pattern.html

    工厂: 顾名思义类似产品、食品等的一类事物生产的工厂。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

    组成:

    • 工厂 用来创建产品
    • 产品 实现不同种类的产品

    image-20220220150637078

    工厂设计模式的多种实现(how)

    简单工厂

    image-20220221171049173

    特点: 将产品进行抽象

    优点:实现简单, 比较容易理解

    缺点: 扩展除了需要新增产品, 也需要修改工厂类。

    1. 抽象类-披萨产品类

      package com.arithmetic.gof.factory.product;
      
      /**
       * 产品-披萨
       *
       * @author mazhiyuan
       * @date 2022/02/21
       */
      public abstract class Pizza {
      
      	/**
      	 * 产品名字
      	 */
      	protected String name;
      
      	/**
      	 * 披萨的味道
      	 */
      	public abstract void pizzaTaste();
      
      	public void setName(String name) {
      		this.name = name;
      	}
      }
      
    2. 具体不同的产品类

      package com.arithmetic.gof.factory.product;
      
      /**
       * 芝士披萨
       *
       * @author mazhiyuan
       * @date 2022/02/21
       */
      public class CheesePizza extends Pizza {
      
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作芝士披萨");
      	}
      
      }package com.arithmetic.gof.factory.product;
      
      
      
      package com.arithmetic.gof.factory.product;
      
      /**
       * 希腊披萨
       *
       * @author mazhiyuan
       * @date 2022/02/21
       */
      public class GreekPizza extends Pizza {
      
         @Override
         public void pizzaTaste() {
            System.out.println(" 给制作希腊披萨");
         }
      
      }
      
      package com.arithmetic.gof.factory.product;
      
      /**
       * 胡椒披萨
       *
       * @author mazhiyuan
       * @date 2022/02/21
       */
      public class PepperPizza extends Pizza {
      
         @Override
         public void pizzaTaste() {
            System.out.println("给制作胡椒披萨");
         }
      
      }
      
    3. 制作/创建工厂类

      package com.arithmetic.gof.factory;
      
      
      import com.arithmetic.gof.factory.product.CheesePizza;
      import com.arithmetic.gof.factory.product.GreekPizza;
      import com.arithmetic.gof.factory.product.PepperPizza;
      import com.arithmetic.gof.factory.product.Pizza;
      
      /**
       * 简单的工厂/静态工厂
       *
       * @author mazhiyuan
       * @date 2022/02/21
       */
      public class SimpleFactory {
      
          public static Pizza createPizza(String orderType) {
      
              Pizza pizza = null;
      
              System.out.println("使用简单工厂模式2");
              if (orderType.equals("greek")) {
                  pizza = new GreekPizza();
                  pizza.setName(" 希腊披萨 ");
              } else if (orderType.equals("cheese")) {
                  pizza = new CheesePizza();
                  pizza.setName(" 奶酪披萨 ");
              } else if (orderType.equals("pepper")) {
                  pizza = new PepperPizza();
                  pizza.setName("胡椒披萨");
              }
      
              return pizza;
          }
      
      }
      
      

    工厂方法

    特点: 将产品进行抽象 将工厂抽象 适用于多个工厂 多种具体的产品。产品只有一个抽象抽象产品披萨。

    工厂方法和简单工厂区别:

    • 简单工厂适用于 单个工厂, 工厂是一个具体的创建产品的工厂。
    • 工厂方法, 本质是在简单工厂的基础上,把工厂的创建方法也进行了抽象为接口。 适用于多个工厂,这样在多个工厂进行调用的时候, 因为中间有一个抽象层,具体的调用不需要修改。 只需要扩展工厂种类和工厂对应的产品就可以。

    缺点:分类等级多了内部需要if else进行分支判断

    image-20220221215454815

    image-20220222105712941

    说明:

    • 产品抽象 和 工厂抽象 属于抽象部分==框架
    • 北京 和 伦敦工厂 以及 北京所有披萨 和 伦敦所有披萨 属于具体的子类实现部分。

    产品实现

    1. 抽象产品代码

      package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * 披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public abstract class Pizza {
      	/**
      	 * 产品名字
      	 */
      	protected String name;
      
      	/**
      	 * 披萨的味道
      	 */
      	public abstract void pizzaTaste();
      
      	/**
      	 * 集名称
      	 *
      	 * @param name 的名字
      	 */
      	public void setName(String name) {
      		this.name = name;
      	}
      }
      
      
    2. 具体的产品-北京奶酪披散

      package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * bjcheese披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class BJCheesePizza extends Pizza {
      
      	/**
      	 * 披萨的味道
      	 */
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作北京奶酪披萨");
      	}
      
      }
      
    3. 具体的产品-北京胡椒披萨

      package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * bjpepper披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class BJPepperPizza extends Pizza {
      	/**
      	 * 披萨的味道
      	 */
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作北京胡椒披萨");
      	}
      
      }
      
      
    4. 具体的产品-伦敦奶酪披萨

      package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * ldcheese披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class LDCheesePizza extends Pizza {
      
      	/**
      	 * 披萨的味道
      	 */
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作伦敦奶酪披萨");
      	}
      }
      
    5. 具体的产品-伦敦胡椒披萨

      package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * ldpepper披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class LDPepperPizza extends Pizza {
      	/**
      	 * 披萨的味道
      	 */
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作伦敦胡椒披萨");
      	}
      }package com.arithmetic.gof.factoryMethod.product;
      
      /**
       * ldpepper披萨
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class LDPepperPizza extends Pizza {
      	/**
      	 * 披萨的味道
      	 */
      	@Override
      	public void pizzaTaste() {
      
      		System.out.println("给制作伦敦胡椒披萨");
      	}
      }
      

    工厂实现

    1. 抽象工厂

      package com.arithmetic.gof.factoryMethod.factory;
      
      import com.arithmetic.gof.factoryMethod.product.Pizza;
      
      /**
       * 工厂
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public abstract class Factory {
      
          /**
           * 创建披萨
           *
           * @param orderType 订单类型
           * @return {@code Pizza}
           */
          public abstract Pizza createPizza(String orderType);
      }
      
    2. 具体的工厂-北京工厂

      package com.arithmetic.gof.factoryMethod.factory;
      
      
      import com.arithmetic.gof.factoryMethod.product.BJCheesePizza;
      import com.arithmetic.gof.factoryMethod.product.BJPepperPizza;
      import com.arithmetic.gof.factoryMethod.product.Pizza;
      
      /**
       * bjpizza工厂
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class BJPizzaFactory extends Factory{
      
          /**
           * 创建披萨
           *
           * @param orderType 订单类型
           * @return {@code Pizza}
           */
          @Override
          public Pizza createPizza(String orderType) {
      
              Pizza pizza = null;
              if(orderType.equals("cheese")) {
                  pizza = new BJCheesePizza();
              } else if (orderType.equals("pepper")) {
                  pizza = new BJPepperPizza();
              }
              return pizza;
          }
      }
      
    3. 具体的工厂-伦敦工厂

      package com.arithmetic.gof.factoryMethod.factory;
      
      import com.arithmetic.gof.factoryMethod.product.LDCheesePizza;
      import com.arithmetic.gof.factoryMethod.product.LDPepperPizza;
      import com.arithmetic.gof.factoryMethod.product.Pizza;
      
      /**
       * ldpizza工厂
       *
       * @author mazhiyuan
       * @date 2022/02/22
       */
      public class LDPizzaFactory extends Factory{
          /**
           * 创建披萨
           *
           * @param orderType 订单类型
           * @return {@code Pizza}
           */
          @Override
          public Pizza createPizza(String orderType) {
      
              Pizza pizza = null;
              if(orderType.equals("cheese")) {
                  pizza = new LDCheesePizza();
              } else if (orderType.equals("pepper")) {
                  pizza = new LDPepperPizza();
              }
              return pizza;
          }
      }
      
      

    工厂方法使用

    package com.arithmetic.gof.factoryMethod;
    
    import com.arithmetic.gof.factoryMethod.factory.BJPizzaFactory;
    import com.arithmetic.gof.factoryMethod.factory.Factory;
    import com.arithmetic.gof.factoryMethod.factory.LDPizzaFactory;
    
    public class FactoryMethodMain {
    
        public static void main(String[] args) {
    
            Factory factory = new BJPizzaFactory();
            factory.createPizza("cheese").pizzaTaste();
    
            factory = new LDPizzaFactory();
            factory.createPizza("cheese").pizzaTaste();
        }
    }
    

    抽象工厂

    特点: 抽象的工厂覆盖更广, 抽象的工厂可以创建多个抽象的产品,即多个类别的产品。

    抽象工厂和工厂方法的区别:

    • 工厂方法创建一类抽象产品(如以上实现披萨) , 抽象工厂可以创建多类产品, 多等级产品。
    • 工厂方法内部只有抽象一个创建方法, 抽象工厂内部有多个抽象的创建方法
    • 工厂方法适用于单一产品, 抽象工厂适用于复杂的产品, 系列产品, 产品簇。
    • 抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品

    抽象工厂的组成:

    1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
    2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
    3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
    4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

    参考

    设计模式——抽象工厂 - 知乎 (zhihu.com)

    抽象工厂模式(详解版) (biancheng.net)

    产品实现

    1. 抽象产品1

      interface Product1 {
          public void show();
      }
      
    2. 具体产品1.1

      class ConcreteProduct11 implements Product1 {
      		public void show(){
            
          }
      }
      
    3. 具体产品1.2

      class ConcreteProduct12 implements Product1 {
      		public void show(){
            
          }
      }
      
    4. 抽象产品2

      interface Product2 {
          public void show();
      }
      
    5. 具体产品2.1

      class ConcreteProduct21 implements Product2 {
      		public void show(){
            
          }
      }
      
    6. 具体产品2.2

      class ConcreteProduct22 implements Product2 {
      		public void show(){
            
          }
      }
      

    工厂实现

    1. 抽象工厂

      interface AbstractFactory {
          public Product1 newProduct1();
          public Product2 newProduct2();
      }
      
    2. 具体工厂1

      class ConcreteFactory1 implements AbstractFactory {
          public Product1 newProduct1() {
              System.out.println("具体工厂 1 生成-->具体产品 11...");
              return new ConcreteProduct11();
          }
          public Product2 newProduct2() {
              System.out.println("具体工厂 1 生成-->具体产品 21...");
              return new ConcreteProduct21();
          }
      }
      
    3. 具体工厂2

      class ConcreteFactory2 implements AbstractFactory {
          public Product1 newProduct1() {
              System.out.println("具体工厂 2 生成-->具体产品 12...");
              return new ConcreteProduct12();
          }
          public Product2 newProduct2() {
              System.out.println("具体工厂 2 生成-->具体产品 22...");
              return new ConcreteProduct22();
          }
      }
      
    4. 使用

    工厂设计模式总结

    本质: 工厂设计模式本质是用来解决 产品创建的问题。 多种工厂类型的设计模式, 主要是围绕 单一产品 和 多种产品/多等级的产品问题进行的处理。多等级多种类的产品也可以使用简单工厂/工厂方法进行创建, 但是内部需要使用if else 进行判断。

  • 相关阅读:
    Go Map
    Go XORM
    Go切片
    Go函数
    dockerfile常用指令
    Goroutine并发控制
    Go 格式转换
    Go 常用知识点及实例
    Go 时间
    Go error
  • 原文地址:https://www.cnblogs.com/mzyc/p/15927703.html
Copyright © 2020-2023  润新知