Application of the factory pattern in the Spring framework and JDK source code

In this section we will look at the factory pattern in the Spring framework and JDK source code:

Factory Pattern in Spring

1.1 Simple Factory BeanFactory

The BeanFactory in Spring is an embodiment of the simple factory pattern, passing in a unique identity to get a Bean object

We can see DefaultListableBeanFactory implements this factory method:

Let’s look at the interface BeanFactory:

DefaultListableBeanFactory and the relationship between the BeanFactory:

1.2 Factory method FactoryBean

Implementation principle:

Beans that implement the FactoryBean interface are a class of beans called Factory. The trick is that Spring automatically calls the bean’s getObject() method when it gets the bean using the getBean() call, so instead of returning the factory bean, it returns the value of the bean.getojbect () method.

AbstractFactoryBean:

It might be interesting to take a look at one of FactoryBean’s chestnuts:

Using XML injection:

Specific test code:

Factory schema in JDK

In the JDK source, java.util.Calendar uses the simple factory schema of the factory schema.

Find the getInstance() method and follow it to see the following code:

Factory model practice different payment channels

In the actual project, we will introduce Alipay payment and wechat payment. If we follow the conventional design, we will design as follows:

Design two payment classes AliPay and WeixinPay, and then instantiate the corresponding classes to initiate payment when calling. This method is not very friendly and has weak expansibility for callers. Then we can use the simple factory pattern or the factory method pattern for optimization.

Here we use the simple factory mode to optimize, the factory method mode is the same as we talked about BMW above.

First, different payment channels of factory mode

1.1 class diagram

Once you understand the simple factory pattern, the coding is fairly simple. Let’s look at the class diagram:

1.2 coding

With class diagrams, coding is simple.

1.2.1 Abstract product Roles

The PayChannel interface defines the pay() method:

package com.kfit.factory.example.v2; import java.math.BigDecimal; / * * * * * * PayChannel interface * * * * @author realize "public id SpringBoot" * * @date 2020-11-20 * * @slogan slogan big simple in nature */ public interface PayChannel {/\*\* \* define the payment method \* @param price the price paid \* @return whether the call succeeds, true: succeeds, false: fails. }Copy the code

1.2.2**** Product roles

There are mainly AliPay and WeixinPay:

AliPay:

package com.kfit.factory.example.v2; import java.math.BigDecimal; / * * * * * * * AliPay payment call * * * * @author realize "public number SpringBoot" * * @date 2020-11-20 * * @slogan avenue to simple realization in the sky */ public class AliPay Implements PayChannel{@override public Boolean pay(BigDecimal price){system.out.println (" implements PayChannel, "+price); return true; }}Copy the code

WeixinPay:

package com.kfit.factory.example.v2; import java.math.BigDecimal; / * * * * * * wechat pay call * * * * * @author realize "public number SpringBoot" * * @date 2020-11-20 * * @slogan slogan main to simple realization in the day */ public class WeixinPay Implements PayChannel{@override public Boolean pay(BigDecimal price){system.out.println (" implements PayChannel, "+price); return true; }}Copy the code

1.2.3**** Factory role

Specific factory role PayChannelFactory:

package com.kfit.factory.example.v2; / * * * * * Payment method factory class * * * * @author realize "public number SpringBoot" * * @date 2020-11-20 * * @slogan big Simple in the universe */ public class \* @param type 0: alipay, 1: PayChannelFactory {/\*\* \* this type is usually used in front of the radio button for users to select, we can set the corresponding value on the radio button to 0 or 1 \* @param type 0: alipay, 1: \* @return \*/ public static PayChannel getPayChannel(int type){PayChannel PayChannel = null; if(type == 0){ payChannel = new AliPay(); Else if(type == 1){payChannel = new WeixinPay(); payChannel = new WeixinPay(); / / in payment need to be set up here by some of the configuration information, such as the appId, encryption, etc.} else {throw new RuntimeException (" does not support the mode of payment, type values \ [0 | 1 \], 0: alipay, 1: WeChat payment "); } return payChannel; }}Copy the code

1.3 test

package com.kfit.factory.example.v2; import java.math.BigDecimal; / * * * * * Test pay * * * * @author realize "public number SpringBoot" * * @date 2020-11-20 * * @@slogan Slogan big Simple in nature */ public class Test {/ * * * * * * It's not optimized for users, so we optimized it. \* \* @param args \*/ public static void main(String\[\] args) {// PayChannel PayChannel = PayChannelFactory.getPayChannel(0); PayChannel. Pay (new BigDecimal (88.88)); / / using WeChat pay payChannel = PayChannelFactory getPayChannel (1); PayChannel. Pay (new BigDecimal (88.88)); }}Copy the code

Summary of Factory Model

Let’s take a break in this section and summarize the simple factory, the factory method, and the abstract factory.

I. Factory model

1.1 define

Simple Factory: A Factory class dynamically decides which instance of a product class (inherited from a parent class or interface) should be created based on the parameters passed in.

Factory Method: Defines a Factory parent class to specify a common interface, while a subclass Factory is responsible for generating concrete objects (multiple factories).

Abstract Factory: Provides an interface for creating a series of related or interdependent objects without specifying their concrete classes; Specific factories are responsible for implementing specific product instances (multiple products can be produced in a factory).

1.2 Main Objects

Simple factory: concrete factory (one), abstract product, concrete product

Factory method: Abstract factory, concrete factory (multiple), abstract product, concrete product

Abstract factory: Abstract factory, concrete factory (multiple), abstract product (family), concrete product

Multiple abstract factories have two meanings: implementations of multiple factories, each with multiple methods to create products.

The main objects of the simple Factory pattern are:

The Simple Factory pattern, also known as the Static Factory Method pattern, is not one of the 23 GOF design patterns. Consider the Simple Factory pattern as a special case of the Factory method pattern, and the two fall into the same category.

Factory: Implements the internal logic that creates all instances and provides an externally called method to create the desired product objects.

Abstract Product: Responsible for describing the common interface of the Product

Concrete Products: Describe concrete products produced.

Factory method pattern main objects:

Abstract Factory: A common interface that describes a concrete Factory

ConcreteFactory: Describes concrete factories and creates instances of products for external invocation

Abstract Product: Responsible for describing the common interface of the Product

Concrete Products: Describe concrete products produced

Abstract Factory pattern main objects:

AbstractFactory: A common interface that describes a concrete factory, typically generating two products

ConcreteFactory: Describes concrete factories and creates instances of products for external invocation

AbstractProduct (AbstractProduct) : a public interface that describes abstract products

Concrete Products: Public interfaces that describe concrete products

1.3 the difference between

Factory method pattern:

An abstract product class can be derived from multiple concrete product classes.

An abstract factory class can be derived from multiple concrete factory classes.

Only one instance of a concrete product class can be created per concrete factory class.

Abstract Factory Pattern:

Multiple abstract product classes, each of which can be derived from multiple concrete product classes.

An abstract factory class can be derived from multiple concrete factory classes.

Each concrete factory class can create multiple instances of a concrete product class.

The difference between:

The factory method pattern has only one abstract product class, whereas the Abstract factory pattern has multiple.

The concrete factory class of the Factory method pattern can create only one instance of a concrete product class, whereas the abstract factory pattern can create multiple instances.

1.4 Application Scenarios

Simple Factory model:

You can’t create too many objects in a factory class, otherwise the business logic of the factory class will be too complex, and since the factory class encapsulates the creation of objects, the client should not care about the creation of objects. Applicable scenarios:

(1) Fewer objects need to be created.

(2) The client does not care about the object creation process.

Factory method pattern:

The fundamental difference between a simple factory and a simple factory is that there is only one unified factory class, whereas the factory method provides a factory class for each object to be created. Applicable scenarios:

(1) The customer only knows the name of the factory where the product is created, but not the specific product name. Such as TCL TV factory, Hisense TV factory and so on.

(2) The task of creating an object is performed by one of several concrete sub-factories, whereas an abstract factory only provides an interface to create a product.

(3) Customers do not care about the details of creating products, only about the brand of products

Abstract Factory Pattern:

Application scenarios of abstract factories:

(1) Like the factory method, the client does not need to know the class of the object it is creating.

(2) when a group of objects are required to jointly complete a certain function. And there may be multiple groups of objects that perform different functions.

(3) The system structure is stable and objects will not be added frequently. (Because once the increase will need to modify the original code, inconsistent with the open and close principle).

Second, the summary

Whether it is simple factory pattern, factory method pattern, or abstract factory pattern, they all belong to factory pattern and are very similar in form and characteristics. Their ultimate goal is decoupling.

When used, we do not need to care whether the pattern is a factory method pattern or an abstract factory pattern, because the evolution between them is often confusing.

Often, you will find that the clearly used factory method pattern becomes an abstract factory pattern when a new requirement comes and a new method is added, because the products in the class form product families in a different hierarchy. For the abstract factory pattern, it evolves into the factory method pattern when a method is reduced so that the products provided no longer constitute a product family.

Therefore, when using factory mode, you only need to care about whether the goal of reducing coupling is achieved.