Simple Factory model

Basic introduction

1) The simple factory mode belongs to the creation mode, which is a kind of factory mode. The simple factory pattern is one in which a factory object decides which instance of a product class to create. The simple factory mode is the most simple and practical mode in the factory mode family.
2) Simple factory pattern: defines a class that creates objects and encapsulates the behavior (code) of instantiating objects;
3) In software development, we use the factory pattern when we need to create a large number of objects, classes, or groups of objects.

A simple requirement

A pizza project: It should be easy to expand the pizza variety and easy to maintain
1) There are many types of pizza (GreekPizz, CheesePizz, etc.).
Prepare, bake, cut, box
3) Complete the pizza shop order function.

The traditional way

Public abstract class Pizza {// make Pizza abstract protected String name; Public abstract void prepare() 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; }} public class CheesePizza extends Pizza {@override public void prepare() {system.out.println (" CheesePizza "); }} public class GreekPizza extends Pizza {@override public void prepare() {system.out.println (" GreekPizza "); }} public class OrderPizza {public OrderPizza(){Pizza = null; String orderType; do { orderType = getType(); if (orderType.equals("greek")){ pizza = new GreekPizza(); Pizza. Name = "pizza "; }else if (orderType.equals("cheese")){ pizza = new CheesePizza(); Pizza. Name = "pizza "; }else {system.out.println ("-- exit program --"); break; } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); }while (true); } private String getType() {try {BufferedReader strin = new BufferedReader(new) InputStreamReader(System.in)); System.out.println("input pizza type :"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; }} public class PizzaStore {// equivalent to a client, Public static void main(String[] args) {OrderPizza OrderPizza = new OrderPizza(); }}Copy the code

Advantages and disadvantages of the traditional way

1) Advantages are easy to understand, simple and easy to operate;
2) The disadvantage is that it violates the OCP principle of design pattern, which is open for extension and closed for modification. That is, when we increment the class
When adding new features, try not to change the code, or change the code as little as possible.
** Analysis ** : It is acceptable to change the code, but if we have code to create Pizza in other places, that means we need to change the code, and the code to create Pizza is often multiple places.
Encapsulate the Pizza creation object into a class, so that when we have a new Pizza class, we only need to change the class. Other code that creates Pizza objects does not need to change.

Use the simple factory pattern

  1. Simple factory pattern design: Define a class that instantiates Pizaa objects and encapsulates the code that creates them.

  2. Code demo:

    Public class SimplePizzaFactory {public Pizza createPizza(String type) {Pizza Pizza = null; if (type.equals(“cheese”)) { pizza = new CheesePizza(); Pizza. Name = “pizza “; } else if (type.equals(“greek”)) { pizza = new GreekPizza(); Pizza. Name = “pizza “; } return pizza; }}

Public class OrderPizza {// Rewrite the OrderPizza class, the other classes remain the same // define a simple factory object SimplePizzaFactory; Public OrderPizza(SimplePizzaFactory SimplePizzaFactory){setFactory(SimplePizzaFactory); } public void setFactory(SimplePizzaFactory simplePizzaFactory) { String orderType; // The user entered the type of Pizza Pizza = null; this.simplePizzaFactory = simplePizzaFactory; // Set the simple factory object do {orderType = getType(); pizza = this.simplePizzaFactory.createPizza(orderType); if (pizza ! = null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); }else { break; } }while (true); } private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type :"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; }}}Copy the code

Factory method pattern

Factory method pattern introduction

Defines an abstract method for creating objects, with subclasses deciding which classes to instantiate. The factory method pattern postpones the instantiation of objects to subclasses.

A new requirement

New requirements for the pizza program: Customers can order different flavors of pizza, such as Beijing Cheese Pizza,
Pepper Pizza in Beijing or Cheese Pizza in London or Pepper Pizza in London.
** Factory method pattern design solution: ** Abstracts the instantiation function of pizza items into abstract methods, at different taste points
Meal subclass concrete implementation.

Use the factory method pattern

Public abstract class Pizza {// make Pizza abstract protected String name; Public abstract void prepare() 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 class BJCheesePizza extends Pizza {@override public void prepare() {name = "BJCheesePizza "; System.out.println(" Beijing cheese Pizza preparation materials ~~~~"); }} public class pepperpizza extends Pizza{@override public void prepare() {name = "pepperpizza "; System.out.println(" Beijing pepper Pizza preparation materials ~~~~"); }} public class extends Pizza {@override public void prepare() {public void prepare(); System.out.println(" London cheese Pizza prepared materials ~~~~"); }} public class extends Pizza {@override public void prepare() {public void prepare(); System.out.println(" London pepper Pizza prepared materials ~~~~"); }} public abstract class OrderPizza {// Define an abstract method createPizza, let each factory subclass implement the abstract Pizza createPizza(String orderType); Public OrderPizza(){String orderType; // The user entered the type of Pizza Pizza = null; do { orderType = getType(); pizza = createPizza(orderType); If (pizza! = null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); }else { break; } }while (true); } private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type :"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; }}} public class BJOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) {Pizza Pizza = null; if (orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } return 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; }} public class PizzaStore {public static void main(String[] args) {new BJOrderPizza(); System.out.println("-- exit program --"); }}Copy the code

Abstract Factory pattern

Basic introduction

1) Abstract factory pattern: defines an interface for creating clusters of related or dependent objects without specifying specific classes;
2) Abstract factory pattern can integrate simple factory pattern and factory method pattern;
3) From the perspective of design, abstract factory mode is an improvement (or further abstraction) of simple factory mode;
4) The factory is abstracted into two layers, the AbsFactory(Abstract Factory) and the factory subclass of the concrete implementation. Programmers can use factory subclasses based on the type of object they create. This turns a single simple factory class into a cluster of factories, making it easier to maintain and extend the code.

Use the abstract factory pattern

Pizza and its successors BJCheesePizza, BJPepperPizza, LDCheesePizza, LDPepperPizza remain unchanged

Public Interface AbsFactory {// Let the following factory subclasses instantiate public Pizza createPizza(String orderType); } public class BJFactory implements AbsFactory {@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; }} public class LDFactory implements AbsFactory{@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; } } public class OrderPizza { AbsFactory factory; OrderPizza(AbsFactory factory) { setFactory(factory); } private void setFactory(AbsFactory factory){ Pizza pizza = null; String orderType = ""; // The user enters this.factory = factory; do { orderType = getType(); pizza = factory.createPizza(orderType); If (pizza! = null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); }else {system.out.println (" Order failed! ") ); break; } }while (true); } private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type :"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; }} public class PizzaStore {// equivalent to a client, Public static void main(String[] args) {new OrderPizza(new BJFactory()); }}Copy the code

Factory model summary

1) Significance of factory mode: extract the code of instantiated object and put it into a class for unified management and maintenance, so as to decouple the dependency relationship with the main project. This improves project scalability and maintainability.
2) Three factory modes (simple factory mode, factory method mode, abstract factory mode)
3) Design patterns depend on the principle of abstraction
  • Instead of creating an object instance directly from the new class, place the action of the new class in a factory method and return it. Some books say that variables should not directly hold references to concrete classes.
  • Instead of having a class inherit from a concrete class, inherit from an abstract class or implement an interface.
  • Do not override methods that are already implemented in the base class.

Note: this article draws heavily on the content of silicon Valley public video materials, if there is anything inappropriate immediately delete. If you don’t understand the article, you can go to the official website of Silicon Valley to learn.