Applicable occasions:
7.3 Applicable occasions of factory pattern
The easiest way to create a new object is to use the new keyword and a concrete class. Only in certain situations is the extra complexity of creating and maintaining an object factory worth it. This section summarizes these occasions.
7.3.1 Dynamic Implementation
If you need to create some objects that implement the same interface in different ways, like the previous bicycle example, you can use a factory method or a simple factory object to simplify the process of selecting an implementation. This choice can be made explicitly or implicitly. The former is like the bicycle example, where customers can choose the bicycle model they need; while the XHR factory example described in the next section belongs to the latter. The type of connection object returned in this example depends on the detected bandwidth and network delay. time and other factors. In these situations, you are usually dealing with a series of classes that implement the same interface and can be treated equally. This is the most common reason to use the factory pattern in JavaScript.
7.3.2 Save setup overhead
If objects require complex settings that are related to each other, then using the factory pattern can reduce the amount of code required for each object. This is especially useful if this setup only needs to be done once for all instances of a particular type. Putting this kind of setup code in the constructor of a class is not efficient because even if the setup work is completed, the code will still be executed every time a new instance is created, and doing so will scatter the setup code into different classes. Factory methods are very suitable for this situation. It can be set up once before instantiating all required objects. This approach keeps the setup code in one place, no matter how many different classes are instantiated.
This is especially useful if the class you are using requires loading an external library. Factory methods can check for these libraries and dynamically load those that are not found. These settings code only exists in one place, so it is much easier to change it later.
7.3.3 Use many small objects to form a large object
Factory methods can be used to create objects that encapsulate many smaller objects. Consider the constructor of a bicycle object. A bicycle contains many smaller subsystems: wheels, frame, transmission components, brakes, etc. Factory methods are ideal if you don't want a subsystem to be strongly coupled to a larger object, but want to choose from many subsystems at runtime. Using this technology, you could fit all the bikes you sell on one day with a certain chain, and if you find another chain you like more the next day, you can switch to that new variety. Implementing this change is easy because the constructors of these bicycle classes do not depend on a specific chain variety. The RSS reader example later in this chapter demonstrates the use of the factory pattern in this regard.
The factory pattern mainly provides an interface for creating objects. The factory pattern is divided into three categories according to the formulation in "Java and Patterns":
1. Simple Factory Pattern (Simple Factory)
2. Factory Method Pattern (Factory Method)
3. Abstract Factory Pattern (Abstract Factory)
These three The patterns are progressively more abstract and more general from top to bottom. There is another classification method, which is to regard the simple factory pattern as a special case of the factory method pattern, and the two are classified into one category. The following are two situations when using the factory pattern:
1. It is impossible to predict which class instance needs to be created when coding.
2. The system should not rely on the details of how product class instances are created, combined and expressed
3. Simple Factory Pattern
As the name suggests, this pattern itself is very simple and is used when the business is relatively simple.
It consists of three roles (see the class diagram below for the relationship):
1. Factory role: This is the core of this model and contains certain business logic and judgment logic. In java it is often implemented by a concrete class.
2. Abstract product role: It is generally the parent class inherited by a specific product or the interface implemented. It is implemented in java by interface or abstract class.
3. Specific product role: The object created by the factory class is an instance of this role. Implemented by a concrete class in java.
So how to use the simple factory mode? Let me give you an example. I think this is much easier to understand than a long theoretical description! Let’s treat that upstart: P
After using the simple factory model, now the upstart only needs to sit in the car and say to the driver: "Drive". Let’s see how it is implemented:
//Abstract product role
public interface Car{
public void drive();
}
//Specific product role
public class Benz implements Car{
public void drive() {
System. out.println("Driving Benz ");
}
}
public class Bmw implements Car{
public void drive() {
System.out.println("Driving Bmw ");
}
}
. . . (I won’t write about Audi :P)
//Factory class role
public class Driver{
//Factory method
//Note that the return type is abstract product role
public static Car driverCar(String s)throws Exception {
/ /Judge the logic and return the specific product role to the Client
if(s.equalsIgnoreCase("Benz")) return new Benz();
else if(s.equalsIgnoreCase("Bmw"))
return new Bmw();
...
else throw new Exception();
. . .
//Welcome the upstarts...
public class Magnate{
public static void main(String[] args){
try{
//Tell the driver I’m taking a Mercedes today
Car car = Driver.driverCar( "benz");
//Give the command: drive
car.drive();
. . .
If you put all classes in one file, please don’t forget that only one class can be declared public. The relationship between classes in the program is as follows:
This is the simple factory pattern. The following are its benefits:
First of all, after using the simple factory pattern, our program is no longer "sick" and is more in line with the real situation; and the client is exempted from the responsibility of directly creating product objects, and is only responsible for "consuming" products (As the nouveau riche do).
Let’s analyze the simple factory model from the opening and closing principle. When the upstart adds a car, as long as it complies with the contract established by the abstract product, it can be used by the customer as long as the factory class is notified. So for the product part, it complies with the open-close principle - open for expansion and closed for modification; but the factory part seems not ideal, because every time a car is added, the corresponding business logic must be added to the factory class. and judgment logic, which obviously violates the opening and closing principle.
For such a factory class (in our case, the driver master), we call it the almighty class or the God class.
The example we gave is the simplest case, but in actual application, the product is likely to be a multi-level tree structure. Since there is only one factory class in the simple factory pattern to correspond to these products, this may break our god class and exhaust our lovely programmers :(
As I mentioned earlier, the simple factory pattern is suitable for business In simple cases, it may not be suitable for complex business environments. This should be the factory method pattern!
4. Let’s take a look at its composition first:
1. Abstraction Factory role: This is the core of the factory method pattern. It has nothing to do with the application. It is the interface that the specific factory role must implement or the parent class that must be inherited.
2. The specific factory role. : It contains code related to specific business logic. It is called by the application to create the corresponding specific product object. In Java, it is implemented by a specific class.
3. Abstract product role: It is the parent class inherited by the specific product. Or an implemented interface. In java, there are generally abstract classes or interfaces to implement.
4. Specific product roles: The objects created by specific factory roles are implemented by specific classes in java. Use a class diagram to clearly represent the relationship between them:
We still use a complete example to see how the various roles in the factory model are coordinated. In other words, the upstart business is getting bigger and bigger. He has more and more cars. This is really hard for the driver. He has to remember, maintain, and use all the cars. So the upstart sympathized with him and said: It’s only because of you and me for so many years! Go on, you don’t have to work so hard in the future, I will allocate a few people to you, you just need to take care of them! So, the management of the factory method pattern appeared as follows:
//Abstract product roles, specific product roles and simplicity. The factory pattern is similar, but a little more complicated, here it is abbreviated. new Benz();
}
}
public class BmwDriver implements Driver{
public Car driverCar() {
return new Bmw();
}
}
......//It should form a corresponding relationship with the specific product , here is a little...
//Please invite Mr. Upstart
public class Magnate
{
public static void main(String[] args)
{
try{
Driver driver = new BenzDriver();
Car car = driver .driverCar();
car.drive();
}catch(Exception e)
{ }
}
}
The factory method uses an abstract factory role as the core instead of using the concrete class as the core in the simple factory pattern. Let's see what the factory method pattern brings us? Use the opening and closing principle to analyze the factory method pattern. When a new product (i.e., a car for the upstart) is produced, it can be used by customers as long as it is generated according to the contract provided by the abstract product role and abstract factory role without having to modify any existing code. It seems that the factory method pattern is completely consistent with the opening and closing principle!
Using the factory method pattern is sufficient to meet most business needs we may encounter. But when there are many types of products, there will be a large number of corresponding factory classes, which should not be what we want. So I suggest that in this case, use the simple factory pattern and the factory method pattern to reduce the factory classes: that is, for similar types on the product tree (usually brothers in the leaves of the tree), use the simple factory pattern to accomplish.
Of course, special situations require special treatment: if there are different product trees in the system, and there are product families on the product tree, then the abstract factory pattern may be used in this case.
V. Summary
Let us take a look at the inspiration given to us by the simple factory pattern and the factory method pattern:
If we do not use the factory pattern to implement our example, maybe the code will be reduced a lot - only the existing cars need to be implemented, no Use polymorphism. But it is very poor in terms of maintainability and scalability (you can imagine the classes that will be affected after adding a car). Therefore, in order to improve scalability and maintainability, it is worthwhile to write more code.
6. Abstract Factory Pattern
First, let’s understand what a product family is: a family of products with related functions located in different product hierarchical structures. If you can clearly understand this concept just by reading this sentence, I have to admire you. Let us use an example to illustrate it vividly.
BmwCar and BenzCar in the picture are two product trees (product hierarchy); and BenzSportsCar and BmwSportsCar as shown in the picture are one product family. They can all be put into the sports car family, so the functions are related. In the same way, BMWBussinessCar and BenzSportsCar are also a product family.
Back to the topic of the abstract product pattern, it can be said that the difference between it and the factory method pattern lies in the complexity of the objects that need to be created. Moreover, the abstract factory pattern is the most abstract and general among the three. The purpose of the abstract factory pattern is to provide an interface for the client to create product objects in multiple product families. Moreover, the following conditions must be met to use the abstract factory pattern:
1. There are multiple product families in the system, and the system can only consume one of the products at a time
2. Products belonging to the same product family can be used accordingly.
Let’s take a look at the various roles of the abstract factory pattern (the same as those of the factory method):
Abstract factory role: This is the core of the factory method pattern, which has nothing to do with the application. It is the interface that a specific factory role must implement or the parent class that must be inherited. In java it is implemented by abstract classes or interfaces.
Specific factory role: It contains code related to specific business logic. Called by an application to create an object corresponding to a specific product. In java it is implemented by concrete classes.
Abstract product role: It is the parent class inherited by a specific product or the interface implemented. In Java, there are generally abstract classes or interfaces to implement.
Specific product role: The object created by the specific factory role is an instance of this role. It is implemented by specific classes in java.
After watching the first two modes, you should have an idea of the coordination between the various characters in this mode, so I won’t give specific examples. Just be sure to meet the conditions for using the abstract factory pattern, otherwise even if there are multiple product trees, there are also product families, but they cannot be used
For more articles related to the three Java factory patterns, please follow PHP Chinese website!