3. Factory pattern of Java design pattern

xiaocantian 2020-11-11 11:01:32
factory pattern java design pattern


Basic needs :

  • A pizza shop needs to order different kinds of pizzas

The traditional way :

  • Realize the idea

    • In the ordering class, different pizza entity classes are directly created according to different input of users
  • UML Class diagram

  • Code implementation

    • Pizza

      • // Abstract parent class
        public abstract class Pizza {
        String name;
        public abstract void prepare();
        public void bake() {
        System.out.println(this.name + " Pizza baking ");
        }
        public void cut() {
        System.out.println(this.name + " Pizza cutting ");
        }
        public void box() {
        System.out.println(this.name + " The pizza is packed ");
        }
        }
        // Cheese pizza Subclass 1
        public class CheesePizza extends Pizza {
        public CheesePizza(String name) {
        this.name = name;
        }
        @Override
        public void prepare() {
        System.out.println(this.name + " The pizza is prepared from raw materials ");
        }
        }
        // Greek pizza Subclass 2
        public class GreekPizza extends Pizza{
        public GreekPizza(String name) {
        this.name = name;
        }
        @Override
        public void prepare() {
        System.out.println(this.name + " The pizza is prepared from raw materials ");
        }
        }
        
    • Ordering

      • public class PizzaStore {
        public static void main(String[] args) {
        new PizzaStore().OrderPizza();
        }
        // How to order pizza The traditional way is to use new The method of subclass is used to return the corresponding pizza
        public void OrderPizza() {
        Pizza pizza;
        Scanner scanner = new Scanner(System.in);
        String orderType;
        while (true) {
        System.out.println(" Enter the type of pizza :");
        orderType = scanner.nextLine();
        if (StringUtils.equals("cheese", orderType)) {
        pizza = new CheesePizza("cheese");
        } else if (StringUtils.equals("greek", orderType)) {
        pizza = new GreekPizza("greek");
        } else {
        System.out.println(" There's no pizza of this type ");
        break;
        }
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        }
        }
        }
        

Defects and improvements :

  • In the ordering method , Direct adoption new The method of subclass is used to return the corresponding pizza , In violation of the design pattern ocp principle , Open to expansion , Turn off for changes . That is, when we add new functions to the class , Try not to change the code , Or change the code as little as possible
  • If you add a new type of pizza , It needs to be modified OrderPizza Method implementation of , If you have more than one creation Pizza All methods need to be modified
  • Create Pizza Objects are encapsulated in a class , So we have new Pizza When kind , Just modify the class , Others have created Pizza Object code does not need to be modified ——> Simple factory model

Simple factory model :

  • The simple factory pattern is a creation pattern , It's a kind of factory model . The simple factory pattern is an instance of which product class is created by a factory object . The simple factory pattern is the simplest and most practical pattern in the family of factory patterns

  • Simple factory model : Defines a class for creating objects , This class encapsulates the behavior of the instantiated object ( Code )

  • When we're going to use a lot to create a certain 、 When a class or a batch of objects , It will use the factory mode

  • Realize the idea

    • Create a simple factory class SimpleFactory, Provide a create Pizza Methods ,PizzaStore to want to Pizza when , It can be obtained directly from the factory
  • UML Class diagram

  • Code implementation

    • // Simple factory class Pizza Class and implementation class are the same as
      public class SimpleFactory {
      // establish Pizza Methods It can be called in multiple places , If you need to add other kinds of Pizza You only need to modify the internal implementation of this method , No callers are required
      public Pizza createPizza(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new CheesePizza("cheese");
      } else if (StringUtils.equals("greek", orderType)) {
      pizza = new GreekPizza("greek");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      // Simple factory is also called static factory It can directly provide static methods to obtain objects
      public static Pizza createPizza1(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new CheesePizza("cheese");
      } else if (StringUtils.equals("greek", orderType)) {
      pizza = new GreekPizza("greek");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      }
      
    • public class PizzaStore {
      public static void main(String[] args) {
      // new PizzaStore().OrderPizza();
      new PizzaStore(new SimpleFactory());
      }
      private SimpleFactory simpleFactory;
      public PizzaStore(SimpleFactory simpleFactory) {
      this.simpleFactory = simpleFactory;
      OrderPizza();
      }
      private void OrderPizza() {
      Pizza pizza;
      Scanner scanner = new Scanner(System.in);
      String orderType;
      while (true) {
      System.out.println(" Enter the type of pizza :");
      orderType = scanner.nextLine();
      // adopt Pizza The factory gets Pizza object
      pizza = simpleFactory.createPizza(orderType);
      if (null == pizza) {
      break;
      }
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      }
      }
      }
      

Factory method model :

  • On the basis of the above, new requirements have been added , Need to be in every kind of pizza Plus the place of origin , for example Cheese in Beijing pizza、 Pepper in Beijing pizza Or London cheese pizza、 Pepper in London pizza

  • Ideas 1: You can use the simple factory model , Two new simple factories ,BJPizzaSimpleFactory and LDPizzaSimpleFactory But considering the scale of the project , And software maintainability 、 Scalability is not particularly good

  • Ideas 2: Adopt the factory approach model

    • Abstract the instantiation function of pizza project into abstract method , In the different taste ordering subclass, the specific implementation of
    • Factory method model : Defines an abstract method for creating objects , It's up to the subclass to decide which class to instantiate . The factory method pattern defers the instantiation of objects to subclasses .
  • Realize the idea

    • stay PizzaStore Add a create Pizza Abstract method , from BJPizzaStore and LDPizzaStore To achieve , So far, the two subclasses create Pizza They're all from their own regions
  • UML Class diagram

  • Code implementation

    • // Abstract classes with abstract methods
      public abstract class PizzaStore {
      public static void main(String[] args) {
      // Select the factory according to the region ? What's the benefit of not having a product and creating multiple simple factories
      String area = "BJ";
      if (area.equals("BJ")) {
      new BJPizzaStore();
      } else {
      new LDPizzaStore();
      }
      }
      public PizzaStore() {
      OrderPizza();
      }
      private void OrderPizza() {
      Pizza pizza;
      Scanner scanner = new Scanner(System.in);
      String orderType;
      while (true) {
      System.out.println(" Enter the type of pizza :");
      orderType = scanner.nextLine();
      // Use abstract methods to create Pizza, Using different implementation classes will result in different pizzas
      pizza = createPizza(orderType);
      if (null == pizza) {
      break;
      }
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      }
      }
      // establish Pizza Abstract method of Implemented by subclasses
      public abstract Pizza createPizza(String orderType);
      }
      
    • // Subclass 1
      public class BJPizzaStore extends PizzaStore {
      @Override
      public Pizza createPizza(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new BJCheesePizza("BJCheese");
      } else if (StringUtils.equals("pepper", orderType)) {
      pizza = new BJPepperPizza("BJPepper");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      }
      // Subclass 2
      public class LDPizzaStore extends PizzaStore {
      @Override
      public Pizza createPizza(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new BJCheesePizza("LDCheese");
      } else if (StringUtils.equals("pepper", orderType)) {
      pizza = new BJPepperPizza("LDPepper");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      }
      

Abstract factory pattern :

  • The abstract factory pattern defines a interface Used to create related or dependent object clusters , Without specifying a specific class , You can integrate the simple factory model with the factory approach pattern

  • From the perspective of design , Abstract factory pattern is the improvement of simple factory pattern ( Or further abstraction ), Abstract the factory into two layers ,

  • Realize the idea

    • establish AbsFactory( Abstract factory ) And the specific implementation of the factory subclass , Create a factory subclass when using
  • UML Class diagram

  • Code implementation

    • // Abstract factory class
      public interface AbsFactory {
      Pizza createPizza(String orderType);
      }
      // Subclass 1
      public class BJFactory implements AbsFactory {
      @Override
      public Pizza createPizza(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new BJCheesePizza("BJCheese");
      } else if (StringUtils.equals("pepper", orderType)) {
      pizza = new BJPepperPizza("BJPepper");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      }
      // Subclass 2
      public class LDFactory implements AbsFactory {
      @Override
      public Pizza createPizza(String orderType) {
      Pizza pizza = null;
      if (StringUtils.equals("cheese", orderType)) {
      pizza = new BJCheesePizza("LDCheese");
      } else if (StringUtils.equals("pepper", orderType)) {
      pizza = new BJPepperPizza("LDPepper");
      } else {
      System.out.println(" There's no pizza of this type ");
      }
      return pizza;
      }
      }
      
    • public class PizzaStore {
      public static void main(String[] args) {
      new PizzaStore(new BJFactory());
      }
      private AbsFactory factory;
      public PizzaStore(AbsFactory factory) {
      // Declare the need for factory class objects here , When you use it, you can directly create the subclass object of the abstract factory
      this.factory = factory;
      OrderPizza();
      }
      private void OrderPizza() {
      Pizza pizza;
      Scanner scanner = new Scanner(System.in);
      String orderType;
      while (true) {
      System.out.println(" Enter the type of pizza :");
      orderType = scanner.nextLine();
      // Use abstract methods to create Pizza, Using different implementation classes will result in different pizzas
      pizza = factory.createPizza(orderType);
      if (null == pizza) {
      break;
      }
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      }
      }
      }
      

jdk Source code :

  • stay Calendar Class getInstance() The simple factory pattern is useful in the method

  • public static Calendar getInstance()
    {
    // Get the default zone and aLocale
    return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }
    public static Calendar getInstance(TimeZone zone,
    Locale aLocale)
    {
    return createCalendar(zone, aLocale);
    }
    private static Calendar createCalendar(TimeZone zone,
    Locale aLocale)
    {
    CalendarProvider provider =
    LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
    .getCalendarProvider();
    if (provider != null) {
    try {
    return provider.getInstance(zone, aLocale);
    } catch (IllegalArgumentException iae) {
    // fall back to the default instantiation
    }
    }
    Calendar cal = null;
    // The simple factory pattern is used here to create Calender object adopt aLocale Different suffixes
    if (aLocale.hasExtensions()) {
    String caltype = aLocale.getUnicodeLocaleType("ca");
    if (caltype != null) {
    switch (caltype) {
    case "buddhist":
    cal = new BuddhistCalendar(zone, aLocale);
    break;
    case "japanese":
    cal = new JapaneseImperialCalendar(zone, aLocale);
    break;
    case "gregory":
    cal = new GregorianCalendar(zone, aLocale);
    break;
    }
    }
    }
    ......
    return cal;
    }
    

matters needing attention :

  • significance : Extract the code of the instantiated object , Put the same management and maintenance in a class , Achieve the goal of dependency decoupling in the project , Improve the expansibility and maintainability of the project
  • Rely on the abstract principle ( Try to rely on abstract things )
    • When you create an object , Do not use new, It's going to be new Put things in a factory and return to
    • Don't let a class inherit a concrete class , Instead, it inherits abstract classes or implements interfaces , Don't override the base class to summarize the implemented methods
版权声明
本文为[xiaocantian]所创,转载请带上原文链接,感谢

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云