“This is the 13th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
Abstract Factory pattern
The Abstract Factory Pattern creates other factories around a gigafactory. The gigafactory is also known as the factory of other factories. This type of design pattern is the creation pattern, which provides the best way to create objects.
In the abstract Factory pattern, an interface is a factory responsible for creating a related object, without explicitly specifying their classes. Each generated factory can provide objects according to the factory pattern.
Intent: Provide an interface for creating a series of related or interdependent objects without specifying their concrete classes.
Main solution: The main solution is interface selection.
When to use: The products of the system have more than one product family, and the system only consumes the products of one of these family.
How to solve it: Define multiple products within a product family.
Key code: the aggregation of multiple similar products in a factory.
Disadvantages: Product family extension is very difficult, adding a product in a family requires both code in the abstract and code in the concrete.
Use scenario: 1, QQ change skin, a set of change together. 2. Generate programs for different operating systems.
Note: Product family is difficult to expand, product level is easy to expand.
Application example: Each brand of automobile has its own production line, such as automatic transmission production line, manual transmission production line. The process of a production line is not easy to disassemble adjustment, it is best to replace the whole replacement. National shift station policy, all cars need to add air bags, equivalent to the need to add a production line to install air bags, namely: product family is difficult to expand. But also reflects his mandatory, forced each production line to enforce.
implementation
Automatic transmission production line Manual car blocking production line air bag production line
Step 1
Create an interface for the shape.
public interface Shape {
void draw();
}
Copy the code
Step 2
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."); }}Copy the code
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); }}Copy the code
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); }}Copy the code
Step 3
Create an interface for color.
public interface Color {
void fill();
}
Copy the code
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."); }}Copy the code
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
Copy the code
public class Blue implements Color { @Override public void fill() { System.out.println("Inside Blue::fill() method."); }}Copy the code
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);
}
Copy the code
Step 6
Create a factory class that extends AbstractFactory to generate an object of the 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; }}Copy the code
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; }}Copy the code
Step 7
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; }}Copy the code
Create a factory creator/generator class to retrieve factories by passing shape or color information.
Step 8
AbstractFactory is obtained using FactoryProducer, and objects of the entity class are obtained by passing type information.
Public class AbstractFactoryPatternDemo {public static void main (String [] args) {/ / to get shape the factory AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); Shape1 = shapeFactory.getShape(" Circle "); shapeFactory.getShape(" Circle "); // Call Circle's draw method shape1.draw(); Shape2 = shapeFactory.getShape(" Rectangle "); // Call Rectangle's draw method shape2.draw(); Shape3 = shapeFactory.getShape(" Square "); // call Square's draw method shape3.draw(); / / to get the COLOR the factory AbstractFactory colorFactory = FactoryProducer. GetFactory (" COLOR "); Color1 = colorFactory.getColor(" Red "); // Call Red's fill method color1.fill(); Color2 = colorFactory.getColor("Green"); // Call Green's fill method color2.fill(); Color3 = colorFactory.getColor(" Blue "); // Call Blue's fill method color3.fill(); }}Copy the code
Step 9
Execute the program and output the result:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.
Copy the code
Conclusion:
The biggest characteristic of abstract factory is double factory; Through the external factory ADAPTS the internal factory. In my opinion, it does not solve the problem of simple factory mode explosion. And it is not a dynamic combination (distinguished from the bridge mode), the key difference is that the factory is replaced as a whole by a set of processes. The smallest units are not enough to be extracted for common use and do not have or need to be replaced flexibly. The biggest advantage is that it provides an optimal way to create objects, especially when multiple objects in a product family are designed to work together, ensuring that clients always use only objects in the same product family
Source application
In the java.sql.Connection interface
A Statement, PreparedStatement, and CallableStatement obtained from a Connection in MySQL must all be MySQL because they are all one product family. The SQL executor obtained from SQL Server must be the SQL executor corresponding to SQL Server.
If a new database appears in the future, and you want to use it in Java, you need to extend the product family and implement the related interface, without modifying the original interface