Factory mode
extraction
Scene introduction
Look at a pizza project: it should be convenient for the expansion of pizza types and maintenance
1. There are many kinds of pizza (such as greenpizza, CheesePizz, etc.)
2. Pizza making includes prepare, bake, cut and box
3. Complete the pizza shop ordering function.
(1) Pizza's parent abstract class
//Abstract the Pizza class public abstract class Pizza { protected String name; //name //The raw materials are different for different pizza, so we make it into an abstract method public abstract void prepare(); public void bake() {System.out.println(name + " baking;");} public void cut() {System.out.println(name + " cutting;");} //pack public void box() {System.out.println(name + " boxing;");} public void setName(String name) {this.name = name;} }
(2) Order pizza
public class OrderPizza { // constructor public OrderPizza() { Pizza pizza = null; String orderType; // Type of pizza ordered do { orderType = getType(); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" Greek pizza "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" Cheese pizza "); } else { break; } //Output pizza production process pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } private String getType() {//A private inner class used to get the kind of pizza the user wants 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 ""; } } }
(3) Cheese pizza, Greek pizza, etc
Directly inherit the parent pizza class:
public class CheesePizza extends Pizza { @Override public void prepare() { // TODO Auto-generated method stub System.out.println(" Prepare raw materials for making cheese pizza "); } }
Greek pizza
public class GreekPizza extends Pizza { @Override public void prepare() { // TODO Auto-generated method stub System.out.println(" Prepare raw materials for Greek pizza "); } }
(4) Pizza store class, equivalent to a client
//It is equivalent to a client and sends out a subscription public class PizzaStore { public static void main(String[] args) { // TODO Auto-generated method stub new OrderPizza(); } }
The above is programming with common ideas
Advantages and disadvantages of common mode
1. The advantages are easy to understand, simple and easy to operate.
2. The disadvantage is that it violates the ocp principle of design pattern, that is, it is open to extension and closed to modification. That is, when we add new functions to the class, we 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 (Pepper Pizza), we need to make the following modifications:
Simple factory mode
Analysis: it is acceptable to modify the code, but if we also have the code to create Pizza in other places, it means that we also need to modify it, and the code to create Pizza often has many places.
Idea: encapsulate the created Pizza object 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 mode. Just take any subclass of Pizza you want from the factory. Don't contact privately.
introduce
1. The simple factory mode belongs to the creation mode, which is a kind of factory mode. The simple factory pattern is a factory object that determines 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 for creating objects, which encapsulates the behavior (code) of instantiating objects
3. In software development, when we will use a lot of to create a certain object, a certain class or a batch of objects, we will use the factory mode
Code improvement
Design scheme of simple factory pattern: define a class that can instantiate Pizza objects and encapsulate the code to create objects.
//Simple factory class public class SimpleFactory { //The orderType returns the corresponding Pizza object //Simple factory mode is also called static factory mode. This static method can directly pass the class name Method name public static Pizza createPizza2(String orderType) { Pizza pizza = null; System.out.println("Use simple factory mode 2"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" Greek pizza "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" Cheese pizza "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("Pepper pizza"); } return pizza; } }
orederpizza can be changed to the following form:
public class OrderPizza2 { Pizza pizza = null; String orderType = ""; // constructor public OrderPizza2() { do { orderType = getType(); pizza = SimpleFactory.createPizza2(orderType);//Here, you can call the static method directly // Output pizza if (pizza != null) { // Order succeeded pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" Failed to order pizza "); break; } } while (true); } // Write a method to get the type of pizza customers want to order 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 ""; } } }
You can directly call new orderpizza 2 in the client.
Factory method model
The core idea is to delay the creation of special classes until the subclass is initialized.
Scene: new demand of pizza project: when ordering pizza, customers can order pizza with different flavors, such as cheese pizza in Beijing, pepper pizza in Beijing, cheese pizza in London and pepper pizza in London.
introduce
Factory method pattern design scheme: abstract the instantiation function of pizza project into abstract methods and implement them in different taste ordering subclasses.
Factory method pattern: defines an abstract method to create an object, and the subclass determines the class to be instantiated. The factory method pattern defers instantiation of objects to subclasses.
code
Key parts:
OrderPizza class
public abstract class OrderPizza { //Define an abstract method, createPizza, and let each factory subclass implement it by itself abstract Pizza createPizza(String orderType); // constructor public OrderPizza() { Pizza pizza = null; String orderType; // Type of pizza ordered do { orderType = getType(); pizza = createPizza(orderType); //Abstract method, which is completed by the factory subclass //Output pizza production process pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } // Write a method to get the type of pizza customers want to order 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 ""; } } }
BJOrderPizza class:
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(); } // TODO Auto-generated method stub return pizza; } }
LDOrderPizza class:
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(); } // TODO Auto-generated method stub return pizza; } }
Store client class:
public class PizzaStore { public static void main(String[] args) { String loc = "bj";//By making input here, you can create different flavors of pizza according to the user's choice if (loc.equals("bj")) { //Create all kinds of Pizza with Beijing flavor new BJOrderPizza(); } else { //Create a variety of pizzas with London flavors new LDOrderPizza(); } // TODO Auto-generated method stub } }
Abstract factory pattern
Basic introduction
1. Abstract Factory Pattern: an interface is defined to create related or dependent object clusters without specifying specific classes
2. Abstract factory pattern can integrate simple factory pattern and factory method pattern.
3. From the design level, the abstract factory pattern is an improvement (or further abstraction) of the simple factory pattern.
4. Abstract the factory into two layers, absfactory (Abstract Factory) and the factory subclass of concrete implementation. Programmers can use the corresponding factory subclasses according to the type of object they create. This turns a single simple factory class into a factory cluster, which is more conducive to code maintenance and expansion.
5. Class diagram:
code
1.AbsFactory
//Abstract layer (Interface) of an abstract factory pattern public interface AbsFactory { //Let the following factory subclass implement it public Pizza createPizza(String orderType); }
2.BJFactory
//This is a factory subclass 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; } }
3.LDFactory
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; } }
4.OrderPizza
public class OrderPizza { AbsFactory factory; // constructor public OrderPizza(AbsFactory factory) {setFactory(factory);} private void setFactory(AbsFactory factory) { Pizza pizza = null; String orderType = ""; // User input this.factory = factory; do { orderType = getType(); // Factory may be a factory subclass in Beijing or a factory subclass in London pizza = factory.createPizza(orderType); if (pizza != null) { // Order ok pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println("Subscription failed"); break; } } while (true); } // Write a method to get the type of pizza customers want to order 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 ""; } } }
5.PizzaStore
public class PizzaStore { public static void main(String[] args) { // TODO Auto-generated method stub //new OrderPizza(new BJFactory()); new OrderPizza(new LDFactory()); } }
Application of factory mode in JDK calendar
Summary of plant mode
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. So as to improve the expansibility and maintainability of the project.
2. Three factory modes (simple factory mode, factory method mode and abstract factory mode)
3. Dependency abstraction principle of design pattern
- When creating an object instance, do not directly the new class, but put the action of the new class in a factory method and return. Some books say that variables do not directly hold references to specific classes.
- Do not let classes inherit concrete classes, but inherit abstract classes or implement interfaces
- Do not override methods already implemented in the base class.