Home  >  Article  >  Java  >  Java factory pattern example code analysis

Java factory pattern example code analysis

WBOY
WBOYforward
2023-04-14 19:16:131124browse

Simple Factory Pattern

Look at a specific requirement

Look at a pizza project: to facilitate the expansion of pizza types and to facilitate maintenance

1) There are many types of pizza (such as GreekPizz, CheesePizz, etc.)

2) Pizza making includes prepare, bake, cut, box

3) Complete the pizza shop Order function.

package com.example.demo.simplefactory.pizzastore.pizza;

/**
 * 将Pizza 类做成抽象
 * @author Administrator
 *
 */
public abstract class Pizza {
  /**
   * 名字
   */
  protected String name;
  
  /**
   * 准备原材料,不同的披萨不一样,因此,我们做成抽象方法
   */
  public abstract void prepare();
  
  public void bake() {
    System.out.println(name + " baking;");
  }
  
  public void cut() {
    System.out.println(name + " cutting;");
  }
  
  public void box() {
    System.out.println(name + " boxing");
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
}
package com.example.demo.simplefactory.pizzastore.pizza;

public class GreekPizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给希腊披萨 准备原材料");
  }

}
package com.example.demo.simplefactory.pizzastore.pizza;

public class CheesePizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给制作奶酪披萨,准备原材料");
  }

}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      if (orderType.equals("greek")) {
        pizza = new GreekPizza();
        pizza.setName(" 希腊披萨 ");
      } else if (orderType.equals("cheese")) {
        pizza = new CheesePizza();
        pizza.setName(" 奶酪披萨 ");
      } else {
        break;
      }
      // 输出pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.simplefactory.pizzastore.order;

/**
 * 相当于一个客户端,发出订购
 * @author Administrator
 *
 */
public class PizzaStore {

  public static void main(String[] args) {
    new OrderPizza();
  }

}

Advantages and disadvantages of the traditional method:

1) The advantage is that it is easier to understand and easy to operate.

2) The disadvantage is that it violates the OCP principle of design pattern, which is open to extension and closed to modification. That is, when we add new functions to a class, try not to modify the code, or modify the code as little as possible.

3) For example, if we want to add a new pizza type at this time, we need to modify it as follows.

package com.example.demo.simplefactory.pizzastore.pizza;

public class PepperPizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给胡椒披萨准备原材料 ");
  }

}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      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("胡椒披萨");
      } else {
        break;
      }
      // 输出pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}

4) Analysis of improved ideas
Analysis: Modifying the code is acceptable, but if we also have code to create Pizza in other places, it means that it also needs to be modified to create Pizza There are often multiple places in the code.
Idea: Encapsulate the creation of Pizza objects into a class, so that when we have a new pizza type, we only need to modify the class, and other codes that create Pizza objects do not need to be modified

Simple Factory Pattern

Basic introduction

1) The simple factory pattern is a creational pattern and a type of factory pattern. The simple factory pattern uses a factory object to decide which product class instance to create. The simple factory pattern is the simplest and most practical pattern in the factory pattern family

2) Simple factory pattern: defines a class that creates objects, and this class encapsulates the lines (code) of instantiated objects

3) In software development, when we create a large number of objects of a certain type, type or batch, we will use the factory pattern.

package com.example.demo.simplefactory.pizzastore.order;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 简单工厂类
 * @author Administrator
 *
 */
public class SimpleFactory {

  public Pizza createPizza(String orderType) {
    Pizza pizza = null;
    System.out.println("使用简单工厂模式");
    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;
  }
  
}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  /*
   * public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do {
   * orderType = getType(); 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("胡椒披萨"); } else { break; } // 输出pizza 制作过程 pizza.prepare();
   * pizza.bake(); pizza.cut(); pizza.box(); } while (true); }
   */
  
  /**
   * 构造器
   * @param simpleFactory
   */
  public OrderPizza(SimpleFactory simpleFactory) {
    setFactory(simpleFactory);
  }
  
  /**
   * 定义一个简单工厂对象
   */
  private SimpleFactory simpleFactory;
  private Pizza pizza = null;
  private void setFactory(SimpleFactory simpleFactory) {
    // 用户输入的
    String orderTypeString = "";
    // 设置简单工厂对象
    this.simpleFactory = simpleFactory;
    do {
      orderTypeString = getType();
      pizza = this.simpleFactory.createPizza(orderTypeString);
      // 输出pizza
      // 订购成功
      if (pizza != null) {
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
      } else {
        System.out.println(" 订购披萨失败 ");
        break;
      }
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.simplefactory.pizzastore.order;

/**
 * 相当于一个客户端,发出订购
 * @author Administrator
 *
 */
public class PizzaStore {

  public static void main(String[] args) {
    //new OrderPizza();
    
    // 使用简单工厂模式
    new OrderPizza(new SimpleFactory());
    System.out.println("~~退出程序~~");
  }

}

Factory method pattern

Look at a new requirement

New requirement for pizza project: When customers order pizza, they can Different flavors of pizza, such as Beijing cheese pizza, Beijing pepper pizza, or London cheese pizza, London pepper pizza.

Idea 1

Use the simple factory pattern to create different simple factory classes, such as BJPizzaSimpleFactory, LDPizzaSimpleFactory, etc. From the current case, it is also Yes, but considering the scale of the project and the maintainability and scalability of the software, it is not particularly good

Idea 2

Use the factory method Pattern

Factory Method Pattern Introduction

Factory Method Pattern Design Plan: Abstract the instantiation function of the pizza project into an abstract method, ordering in different flavors Implemented specifically in subclasses.

Factory method pattern: Defines an abstract method for creating objects, and the subclass determines the class to be instantiated. The Factory Method pattern defers the instantiation of objects to subclasses .

package com.example.demo.factorymethod.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;
import com.fasterxml.jackson.databind.deser.ValueInstantiator.Gettable;

public abstract class OrderPizza {
  
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      createPizza(orderType);
      // 输出Pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 定义一个抽象方法,createPizza,让各个工厂子类自己实现
   * @param orderType
   * @return
   */
  abstract Pizza createPizza(String orderType);
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.factorymethod.pizzastore.order;

import org.apache.tomcat.util.security.Escape;

import com.example.demo.factorymethod.pizzastore.pizza.LDCheesePizza;
import com.example.demo.factorymethod.pizzastore.pizza.LDPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDOrderPizza extends OrderPizza{

  @Override
  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.example.demo.factorymethod.pizzastore.order;

import com.example.demo.factorymethod.pizzastore.pizza.BJCheesPizza;
import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJOrderPizza extends OrderPizza{

  @Override
  Pizza createPizza(String orderType) {
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new BJCheesPizza();
    } else if (orderType.equals("pepper")) {
      pizza = new BJPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJCheesPizza extends Pizza{

  @Override
  public void prepare() {
    setName("北京的奶酪pizza");
    System.out.println(" 北京的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 北京的胡椒pizza ");
    System.out.println(" 北京的胡椒pizza 准备原材料  ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDCheesePizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的奶酪pizza ");
    System.out.println(" 伦敦的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的胡椒pizza ");
    System.out.println(" 伦敦的胡椒pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.order;

public class PizzaStore {

  public static void main(String[] args) {
    // 创建北京口味的各种Pizza
    new BJOrderPizza();
  }

}

Abstract Factory Pattern

Basic Introduction

1) Abstract Factory Pattern: Defines an interface used to create related or dependent Relational object cluster without specifying the specific class

2) Abstract factory pattern can integrate simple factory pattern and factory method pattern

3) From a design perspective, the abstract factory pattern is an improvement (or further abstraction) from the simple factory pattern.

4) Abstract the factory into two layers, AbsFactory (abstract factory) and concrete implemented factory subclasses. Programmers can use corresponding factory subclasses based on the type of objects they create. This turns a single simple factory class into a factory cluster, which is more conducive to code maintenance and expansion.

package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 一个抽象工厂模式的抽象层(接口)
 * @author Administrator
 *
 */
public interface AbsFactory {
  
  /**
   * 让下面的工厂子类来   具体实现
   * @param orderType
   * @return
   */
  Pizza createPizza(String orderType);
}
package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.absfactory.pizzastore.pizza.BJCheesPizza;
import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 这是工厂子类
 * @author Administrator
 *
 */
public class BJFactory implements AbsFactory{

  @Override
  public Pizza createPizza(String orderType) {
    System.out.println("~使用的是抽象工厂模式~");
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new BJCheesPizza();
    } else if (orderType.equals("pepper") ) {
      pizza = new BJPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.absfactory.pizzastore.pizza.LDCheesePizza;
import com.example.demo.absfactory.pizzastore.pizza.LDPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDFactory implements AbsFactory{

  @Override
  public Pizza createPizza(String orderType) {
    System.out.println("~使用的是抽象工厂模式~");
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new LDCheesePizza();
    } else if (orderType.equals("pepper")) {
      pizza = new LDPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.absfactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  private AbsFactory factory;
  
  /**
   * 构造器
   * @param factory
   */
  public OrderPizza(AbsFactory factory) {
    setFactory(factory);
  }
  
  private void setFactory(AbsFactory factory) {
    Pizza pizza = null;
    // 用户输入
    String orderTypeString = "";
    this.factory = factory;
    do {
      orderTypeString = getType();
      pizza = factory.createPizza(orderTypeString);
      if (pizza != null) {
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
      } else {
        System.out.println("~订购失败~");
        break;
      }
    } while (true);
  }

  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJCheesPizza extends Pizza{

  @Override
  public void prepare() {
    setName("北京的奶酪pizza");
    System.out.println(" 北京的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 北京的胡椒pizza ");
    System.out.println(" 北京的胡椒pizza 准备原材料  ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDCheesePizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的奶酪pizza ");
    System.out.println(" 伦敦的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的胡椒pizza ");
    System.out.println(" 伦敦的胡椒pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.order;

public class PizzaStore {
  public static void main(String[] args) {
    new OrderPizza(new BJFactory());
  }
}

Source code analysis of factory mode in JDK-Calendar application
1) The simple factory mode is used in the Calendar class in JDK

public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }
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;

        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;
                }
            }
        }
        if (cal == null) {
            // If no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                cal = new BuddhistCalendar(zone, aLocale);
            } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                       && aLocale.getCountry() == "JP") {
                cal = new JapaneseImperialCalendar(zone, aLocale);
            } else {
                cal = new GregorianCalendar(zone, aLocale);
            }
        }
        return cal;
    }

The above is the detailed content of Java factory pattern example code analysis. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete