1, Overview
Factory Pattern is one of the most commonly used design patterns in Java. This type of design pattern is a creation pattern, which provides the best way to create objects.
In factory mode, when creating objects, we do not expose the creation logic to the client, and point to the newly created objects by using a common interface.
As the name suggests, factory is to create products. According to whether the products are specific products or specific factories, it can be divided into simple factory mode and factory method mode. According to the degree of abstraction of factories, it can be divided into factory method mode and abstract factory mode. This pattern is used to encapsulate and manage the creation of objects.
Core essence:
Replace the factory method with new.
The implementation class will be selected to create objects for unified management and control. This decouples the caller from our implementation class.
effect:
It realizes the separation of creator and caller
Classification:
Simple factory mode: used to produce any product with the same level structure (for adding new products, the existing code needs to be overwritten)
Factory method mode: it is used to produce fixed products in the same hierarchical structure (any product can be added)
Abstract factory pattern: create other factories around one super factory. The super factory is also known as the factory of other factories.
Meet three of the seven principles of OOP:
Opening and closing principle: open to expansion and close to modification (reduce new risks caused by maintenance)
Dependency Inversion Principle: the high level should not rely on the low level, but should be interface oriented programming (which is more conducive to the upgrading and expansion of code structure)
Dimitri's Law: don't know what you shouldn't know. A class should keep the least understanding of other objects and reduce the degree of coupling
(only communicate with friends and don't talk to strangers to reduce code bloat)
The overview is not easy to understand, so we can more intuitively understand the differences between these modes through the code
1. Simple factory mode (static factory mode)
Abstractcar abstract class
public interface Car { void name(); }
Make cars
public class Wuling implements Car { @Override public void name() { System.out.println("Wuling Hongguang"); } }
public class Tesla implements Car { @Override public void name() { System.out.println("Tesla"); } }
CarFactory: Automobile OEM
public class CarFactory { public static getCar(String car) { if(car.equals("Wuling")){ return new Wuling(); } else if(Tesla.equals("Tesla")) { return new Tesla(); } return null; } }
Demo:
public class Demo { public static void main(String[] arg) { Car car=CarFatory.getCar("Wuling"); Car car2=CarFatory.getCar("Tesla"); car.name(); car2.name(); } }
2. Factory method mode
Abstractcar abstract class
public interface Car { void name(); }
//Factory method model public interface CarFactory { Car getCar(); }
Make cars
public class Wuling implements Car { @Override public void name() { System.out.println("Wuling Hongguang"); } }
public class Tesla implements Car { @Override public void name() { System.out.println("Tesla"); } }
CarFactory: Automobile OEM
public class TeslaFactory implements CarFactory { @Override public Car getCar(){ return new Tesla(); } }
public class TeslaFactory implements CarFactory { @Override public Car getCar(){ return new Wuling(); } }
Demo:
public class Demo { public static void main(String[] arg) { Car car=new WulingFatory.getCar(); Car car2=new TeslaFatory.getCar(); car.name(); car2.name(); } }
Comparison between simple factory mode and factory method mode (summary)
The complexity of structure, code, programming and management is simple, and the factory mode is better.
Simple factory mode: although it does not conform to the design principles to some extent, it is actually used most
Factory method mode: extend by adding new factory classes without modifying existing classes
3. Abstract factory mode
We will create the # Shape # and # Color # interfaces and entity classes that implement these interfaces. The next step is to create the abstract factory class {AbstractFactory. Then define the factory classes , ShapeFactory , and , ColorFactory, both of which extend , AbstractFactory. Then create a factory creator / generator class, FactoryProducer.
The AbstractFactoryPatternDemo # class uses # FactoryProducer # to obtain # AbstractFactory # objects. It will pass the Shape information to # AbstractFactory # Shape (CIRCLE / RECTANGLE / SQUARE) to get the type of object it needs. At the same time, it also passes the Color information # Color (RED / GREEN / BLUE) to # AbstractFactory # in order to obtain the type of object it needs.
Step 1
Create an interface for the shape
public interface Shape { void draw(); }
Create an entity class that implements the interface.
Rectangle.java
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } } public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } } public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
Step 3
Create an interface for the color.
public interface Color { void fill(); }
Step 4
Create an entity class that implements the interface.
public class Red implements Color { @Override public void fill() { System.out.println("Inside Red::fill() method."); } } public class Green implements Color { @Override public void fill() { System.out.println("Inside Green::fill() method."); } } public class Blue implements Color { @Override public void fill() { System.out.println("Inside Blue::fill() method."); } }
Step 5
Create abstract classes for Color and Shape objects to get factories.
public abstract class AbstractFactory { public abstract Color getColor(String color); public abstract Shape getShape(String shape); }
Step 6
Create a factory class that extends AbstractFactory and generate the object of entity class based on the given information.
public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } @Override public Color getColor(String color) { return null; } }
public class ColorFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ return null; } @Override public Color getColor(String color) { if(color == null){ return null; } if(color.equalsIgnoreCase("RED")){ return new Red(); } else if(color.equalsIgnoreCase("GREEN")){ return new Green(); } else if(color.equalsIgnoreCase("BLUE")){ return new Blue(); } return null; } }
Step 7
Create a factory creator / generator class to get the factory by passing shape or color information.
public class FactoryProducer { public static AbstractFactory getFactory(String choice){ if(choice.equalsIgnoreCase("SHAPE")){ return new ShapeFactory(); } else if(choice.equalsIgnoreCase("COLOR")){ return new ColorFactory(); } return null; } }
Step 8
Use FactoryProducer to obtain AbstractFactory and obtain the object of entity class by passing type information.
public class AbstractFactoryPatternDemo { public static void main(String[] args) { //Get shape factory AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); //Gets an object with the shape Circle Shape shape1 = shapeFactory.getShape("CIRCLE"); //Call Circle's draw method shape1.draw(); //Gets an object with a rectangular shape Shape shape2 = shapeFactory.getShape("RECTANGLE"); //Call the draw method of Rectangle shape2.draw(); //Gets an object with the shape Square Shape shape3 = shapeFactory.getShape("SQUARE"); //Call Square's draw method shape3.draw(); //Get color factory AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR"); //Get the object with Red color Color color1 = colorFactory.getColor("RED"); //Call Red's fill method color1.fill(); //Gets the object with the color Green Color color2 = colorFactory.getColor("Green"); //Call Green's fill method color2.fill(); //Gets an object with Blue color Color color3 = colorFactory.getColor("BLUE"); //Call Blue's fill method color3.fill(); } }
Step 9
Execute the program and output the results:
Inside Circle::draw() method. Inside Rectangle::draw() method. Inside Square::draw() method. Inside Red::fill() method. Inside Green::fill() method. Inside Blue::fill() method.