Recently, when learning the spring source code, I found that various beans were created during the initialization of the IoC container, and then I saw various beanfactories and factorybeans in the code. Obviously, the spring container used factories in the process of creating beans Design Pattern, then just summarize the factory design pattern.
Factory patterns are divided into simple factory, factory method and abstract factory
1, Simple factory
The essence of a simple factory is that a factory class dynamically determines which product class should be created according to the passed parameters
In the process of creating beans in spring, whether through xml configuration or configuration classes, most beans are created through simple factories. For example, when the container gets the bean name and class type of the bean, it dynamically creates a specific object through reflection, and finally puts the created object into the Map. So why use a simple factory, what are the advantages of a simple factory, and how to use a simple factory? When we learn design patterns, we must know why we use them, what scenarios we use them in, why we don't use new objects when we create objects, and why we use factory patterns and constructor patterns. There must be a reason
Scene: now let's produce the car. They can produce BMW, Mercedes Benz and Volkswagen. Normally, when we create these three cars, we will directly new one object, then call other methods. The code is shown below
Car.java
package factory; public interface Car { void run(); }
BMWCar .java
package factory; public class BMWCar implements Car{ @Override public void run() { // TODO Auto-generated method stub System.out.println("bmw car running..."); } }
BenChiCar .java
package factory; public class BenChiCar implements Car{ @Override public void run() { // TODO Auto-generated method stub System.out.println("benchi car running"); } }
DaZhongCar .java
package factory; public class DaZhongCar implements Car{ @Override public void run() { // TODO Auto-generated method stub System.out.println("dazhong car running..."); } }
SimpleFactoryTest .java
package factory; public class SimpleFactoryTest { public static void main(String[] args) { Car bmw = new BMWCar(); Car benchi = new BenChiCar(); Car dazhong = new DaZhongCar(); bmw.run(); benchi.run(); dazhong.run(); } }
The above code is very simple, and there is no problem. It can be used completely. Now the problem comes
1. Now, with the expansion, there is a requirement that other operations need to be done in the process of automobile production, such as inflating tires, detecting engines, detecting airbags, and so on. Although some work can be completed in the construction method, However, some operations are not suitable for execution in construction methods, so what should I do? Do you need to operate these methods every time you create an object? It's OK to construct an object in only one place. What if you create the object in n multiple places? It will inevitably lead to code duplication.
2. Now the business has changed. We don't produce Mercedes Benz, but production Benz. So we need to change all the places where Mercedes Benz was previously produced into production Benz. How to modify it? Change all places of new BenchiCar() to new BenchiCar()?
Well, then we can use our simple factory method at this time
Create a factory class to solve the above two problems
CarFactory .java
package factory; public class CarFactory { public Car getCar(String carName) { Car car = null; if(carName.equals("bmw")) { car = new BMWCar(); /* *Some operations can be performed uniformly here, such as inflating tires, charging batteries, detecting airbags, etc */ }else if(carName.equals("benchi")) { //car = new BenChiCar(); //For example, to change all previous Mercedes Benz cars into Mercedes Benz cars, just change the above car = new BenChiCar(); Change to the following car = new BenBenCar(); /* *Some operations can be performed uniformly here, such as inflating tires, charging batteries, detecting airbags, etc */ }else if(carName.equals("dazhong")) { car = new DaZhongCar(); /* *Some operations can be performed uniformly here, such as inflating tires, charging batteries, detecting airbags, etc */ } return car; } }
SimpleFactoryTest .java
package factory; public class SimpleFactoryTest { public static void main(String[] args) { CarFactory carFactory = new CarFactory(); Car bmw = carFactory.getCar("bmw"); Car benchi = carFactory.getCar("benchi"); Car dazhong = carFactory.getCar("dazhong"); bmw.run(); benchi.run(); dazhong.run(); } }
Do you think it's ok? In fact, bean factory beans in spring are created through the above simple factory, but they create objects through reflection at the bottom. Simple factory is to let the creator block the creation process and just use it. Can all methods of creating objects be created through the above methods? What if I need to create more and more cars with the expansion of business, and add Toyota, Roewe and BYD? Do you need to modify the getCar() method in the factory method every time? This obviously does not comply with the opening and closing principle in the design pattern (closed for modification and open for extension). What should we do? The following factory method solves this problem
2, Factory method
According to the above problem description, go directly to the code
I won't paste the code repeatedly for the Car interface Car and specific classes above
CarFactory .java
package factorymethod; public interface CarFactory { Car getCar(); }
BMWCarFactory .java
package factorymethod; public class BMWCarFactory implements CarFactory{ @Override public Car getCar() { // TODO Auto-generated method stub return new BMWCar(); } }
FengtianCarFactory .java
package factorymethod; public class FengtianCarFactory implements CarFactory{ @Override public Car getCar() { // TODO Auto-generated method stub return new FengTianCar(); } }
FactoryMethodTest .java
package factorymethod; public class FactoryMethodTest { public static void main(String[] args) { CarFactory benbenFactory = new BenBenCarFactory(); Car benben = benbenFactory.getCar(); benben.run(); CarFactory fengtianFactory = new FengtianCarFactory(); Car fengtian = fengtianFactory.getCar(); fengtian.run(); } }
At this time, if we need to add new automobile brands, we only need to build corresponding factories, The process of creating objects is then deferred to subclasses (implementation class) concrete implementation. The interface is only responsible for defining rules. This design conforms to the opening and closing principle. It is closed for modification and open for extension. Factorybean in spring is this design mode. When the getObject of factorybean is to produce a bean through its implementation class, FactoryBean.getObject does not return an object of factorybean, but returns The corresponding bean created by the factorybean is like fenttianfactory Getcar returns the corresponding fengtian car instead of the factory