Spring uses a lot of factory design patterns, so let’s take a quick look at factory design patterns in this chapter.

The factory design pattern is one of the creation patterns. Definition in GOF:

“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to Subclasses. “Define an interface for creating objects in the base class and let subclasses decide which class to instantiate. The factory method lets instantiation of a class be deferred to subclasses.

In the broad sense, factory patterns can be divided into three types, namely simple Factory pattern, Factory Method pattern and Abstract Factory pattern.

Why to use factory mode:

The main benefit of the factory pattern is decoupling, a term that sounds familiar, and we improved it in the Spring Overview section. At the same time, the main function of the factory pattern is to separate the creation and use of objects. In the case of Spring, it is responsible for the object creation process, so we only need to focus on the object usage process, which greatly simplifies our development process. It also reduces code duplication and maintenance costs. Because of the factory, we do not need to write the creation process of the object.

I. Simple factory model

interface Mouse{
    void sayHi(a);
}
class DellMouse implements Mouse{
    public void sayHi(a){
        System.out.println("hi,DellMouse")}}class HpMouse implements Mouse{
    public void sayHi(a){
        System.out.println("hi,HpMouse")}}class MouseFacotry{
    public static Mouse createMouse(int i){
        switch(i){
            case 0:return new DellMouse();break;
            case 1:return new HpMouse();break;
            default:return null; }}}Copy the code

Simple factories are used less in practice than other factory patterns, and they violate the open-closed principle we discussed in the overview. Because every time you add a function, you need to change the code in switch-case or if-else to add a branch condition. Factory roles, Abstract product roles (Mouse), Concrete product roles (DellMouse, HpMouse)

Factory method mode

The factory method pattern should be the most used pattern in the factory pattern family, and it is the pattern that exists most in a typical project. The factory method pattern is a further development of the simple factory pattern, where instead of providing a single factory class to create all objects, we provide different factories for different objects. That is, each object has a factory corresponding to it.

Applicable scenarios:

  • A class does not know the class of the object it needs: in the factory method pattern, the client does not need to know the class name of the specific product class, only the factory to which it corresponds. The specific product object is created by the specific factory class. The client needs to know the factory class to create the specific product
  • A class specifies which object to create by subclass: in the factory method pattern, an abstract factory class only needs to provide an interface to create a product, and its subclass determines which object to create, using object-oriented polymorphism and Richter’s method
  • Delegate the task of creating an object to one of the factory subclasses. The client can use the factory subclass to create a product subclass without worrying about which factory subclass is used, and specify it dynamically when necessary. The class name of the specific factory class can be stored in the configuration file or database

Role assignment

  • Abstract Factory: The core of the factory method pattern, application-independent. The factory class of any object created in the schema must implement this interface
  • Concrete Factory: This is a Concrete factory class that implements an abstract factory interface, contains logic that is closely related to the application, and is called by the application to create some kind of product object
  • Abstract product: The supertype of an object created by the factory method pattern, which is the common parent or common interface of the product object
  • Concrete Product: This role implements the interface defined by the abstract product role. A specific product is created by a specific factory, and there is often a one-to-one correspondence between them.

Code sample

public interface MouseFactory{
    Mouse getMouse(a);
}
public class DellMouseFactory implements MouseFactory{
    public Mouse getMouse(a){
        return newDellMouse(); }}public class HpMouseFactory implements MouseFactory{
    public Mouse getMouse(a){
        return newHpMouse(); }}public interface Mouse{
    void sayHi(a);
}
public class DellMouse implements Mouse{
    public void sayHi(a){
        System.out.println("hi,DellMouse")}}public class HpMouse implements Mouse{
    public void sayHi(a){
        System.out.println("hi,HpMouse")}}public class Test{
    public static void main(String[] args){
        MouseFactory dellFac = newDellMouseFactory(); Mouse dellMouse = dellFac.getMouse(); dellMouse.sayHi(); }}Copy the code

Abstract factory model

In the factory approach pattern, we actually have an underlying awareness. We all produce the same kind of product. The abstract factory pattern is a further development of the factory approach, in which a factory class can create not just one product, but a set of products. Abstract factory is one of the more difficult factory patterns to understand

Applicable scenario

Client does not need to know it, just like the factory method created by the object class needs a set of objects together to complete some function, and there may be multiple sets of object of complete different function (belong to the same product family of products) system structure is stable, won’t increase frequently object (because the increase would need to modify the original code, not closed principle conjunction)

Role assignment

  • Abstract factory: Is the core of the factory method pattern and is application-independent. The factory class of any object created in the schema must implement this interface.

  • Concrete factory: A concrete factory class that implements an abstract factory interface, contains application-specific logic, and is called by the application to create a product object.

  • Abstract product: A supertype of an object created by the factory method pattern, that is, a common parent or jointly owned interface of the product object.

  • Concrete product: Any product object created by the Abstract factory pattern is an instance of a concrete product class. Products created in an abstract factory belong to the same product family, as opposed to factories that create a single product, as I’ll explain later.

  • The difference between an abstract factory and a factory in the factory method is that an abstract factory produces a complete set of products (at least two products) that must be related or dependent on each other, whereas a factory in the factory method is a factory that produces a single product.

The instance

Let’s take chicken eating as an example. There are all kinds of guns. Suppose there are two types of guns, AK and M4A1, each with a bullet. The way we think about it now is that the factory that produces AK can produce AK bullets in turn, and the factory that produces M4A1 can produce bullets for its lock objects. Create related interfaces:

The gun:

public interface Gun{
     public void shooting(a);
 }
Copy the code

The bullet:

public interface Bullet{
     public void load(a);
 }
Copy the code

Create the corresponding implementation class AK:


 public class AK implements Gun{
     public void shooting(a){
         System.out.println("shooting with AK"); }}Copy the code

M4A1:

public class M4A1 implements Gun{
     public void shooting(a){
         System.out.println("shooting with M4A1"); }}Copy the code

AK bullets:

 public class AK_Bullet implements Bullet {
     @Override
     public void load(a) {
         System.out.println("Load bullets with AK"); }}Copy the code

M4A1 bullet class

 public class M4A1_Bullet implements Bullet {
     @Override
     public void load(a) {
         System.out.println("Load bullets with M4A1"); }}Copy the code

Create a factory

public interface Factory{
     public Gun produceGun(a);
     public Bullet produceBullet(a);
 }
 
 public class AKFac implements Factory{
     public Gun produceGun(a){
         return new AK();
     }
     public Bullet produceBullet(a){
         return newAK_Bullet(); }}public class M4A1Fac implements Factory{
     public Gun produceGun(a){
         return new M4A1();
     }
     public Bullet produceBullet(a){
         return newM4A1_Bullet(); }}Copy the code

test

public class Test{
     public static void main(String[] args){
          Factory factory;
          Gun gun;
          Bullet bullet;
          factory =newAKFac(); bullet=factory.produceBullet(); bullet.load(); gun=factory.produceGun(); gun.shooting(); }}Copy the code

4. To summarize

Well, about the factory design mode, we write so much for the time being, here a lot of content is directly extracted from my notes, and the content in the notes is mostly extracted from Zhihu many years ago, but there is no record of the original author and link, here express thanks, if there is infringement, please contact to delete.