Analysis and summary of simple factory pattern, factory method pattern and abstract factory pattern in factory pattern

factory pattern

There are many variants of the factory pattern, the most common of which are three

  1. Simple Factory Pattern
  2. factory method pattern
  3. abstract factory pattern

Simple factory code analysis

insert image description here

In the UML diagram, we can clearly see the code structure. First, we create a car interface of Car and customize the basic specifications of the car. The way the car can run is to run, so we define an abstract run method.

  • Define the car interface Car
public interface Car {
    
    
     void run();

}

Then we define different car models that implement the car interface

  • BMW class BMW
public class BMW implements Car{
    
    
    @Override
    public void run() {
    
    
        System.out.println("宝马正在启动~~");
    }
}
  • Benz
public class Benz implements Car{
    
    
    @Override
    public void run() {
    
    
        System.out.println("奔驰正在启动~~");
    }
}
  • BYD class BYD
public class BYD implements Car{
    
    
    @Override
    public void run() {
    
    
        System.out.println("比亚迪启动发现没电了~~");
    }
}
  • Then we create the factory class
public class CarFactory {
    
    
    public static Car createCar(String type){
    
    
        if ("宝马".equals(type)){
    
    
            return new BMW();
        }else if ("奔驰".equals(type)){
    
    
            return new Benz();
        }else if ("比亚迪".equals(type)){
    
    
            return new BYD();
        }else{
    
    
            return null;
        }

    }
}

In the above factory class, we passed the incoming string equals which model we want to create, and if it matches, create and return

  • Write a test class for testing
public class Main {
    
    
    public static void main(String[] args) {
    
    
        //用工厂创建一辆宝马
        Car car1 = CarFactory.createCar("宝马");
        if (car1!=null){
    
    
            car1.run();
        }else {
    
    
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆奔驰
        Car car2 = CarFactory.createCar("奔驰");
        if (car2!=null){
    
    
            car2.run();
        }else {
    
    
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆宝骏
        Car car3 =CarFactory.createCar("宝骏");
        if (car3!=null){
    
    
            car3.run();
        }else {
    
    
            System.out.println("没有该车型,无法创建!");
        }
    }
}

operation result

insert image description here

Why are there many variants of the factory pattern? In fact, each variant has advantages and disadvantages, and no design pattern is perfect

For the simple factory pattern, its factory class is generally static, so you can directly call the factory method with the class name to create an instance object

The advantage is that it is simple to implement,

The disadvantage is that when new products need to be added, the code of the factory class must be modified, which does not conform to the principle of opening and closing.

factory method pattern

Factory method pattern code analysis

insert image description here

In the class diagram, compared with the simple factory pattern, we have added a factory interface, and different car manufacturers have implemented the factory class

The car interface and the codes of different brands of cars are the same as above

  • factory interface
public interface Factory {
    
    
    Car creatCar();
}

We declare an abstract method to create a car in the interface

Next, we write different car implementation classes

  • BMW factory class BMWFactory
public class BMWFactory implements Factory{
    
    

    @Override
    public Car creatCar() {
    
    
        return new BMW();
    }
}
  • Mercedes-Benz car factory class BenzFactory
public class BenzFactory implements Factory{
    
    
    @Override
    public Car creatCar() {
    
    
        return new Benz();
    }
}
  • BYD Auto Factory Class BYDFactory
public class BYDFactory implements Factory{
    
    
    @Override
    public Car creatCar() {
    
    
        return new BYD();
    }
}

The above three classes all implement the factory interface

In the next class, we write the test method to create the car instance and call the car method

public class Main {
    
    
    public static void main(String[] args) {
    
    
        BMWFactory bmwFactory = new BMWFactory();
        Car BMWx5 = bmwFactory.creatCar();
        BMWx5.run();
    }
}

operation result

insert image description here

The factory method pattern defines an abstract factory interface, which declares a factory method for creating products, and specific product classes are implemented by specific factory classes. The factory method pattern can have multiple concrete factory classes, and each concrete factory class is responsible for creating a product.

The advantage is that it conforms to the principle of opening and closing, when you need to add new products, you only need to add specific product classes and corresponding specific factory classes, without modifying the code of the abstract factory interface and abstract factory class.

The disadvantage is that it increases the complexity of the system

abstract factory pattern

In order to facilitate package management, we have classified the packages as follows

insert image description here

A new package Logos has been added, in which an interface named Logos is defined

  • Logos interface
public interface Logos {
    
    
    void showLogos();
}

We can see that the interface method of this interface is used to create the car logo, and every class that implements it in the next class must rewrite this interface method

  • BMWLogos class (Logos implementation class, used to create BMW logo)
public class BMWLogos implements Logos{
    
    
    @Override
    public void showLogos() {
    
    
        System.out.println("我的LOGO是宝马");
    }
}
  • BenzLogos class (the implementation class of Logos, used to create the Mercedes-Benz logo)
public class BuziLogos implements Logos{
    
    
    @Override
    public void showLogos() {
    
    
        System.out.println("我的LOGO是奔驰~");
    }
}
  • BYDLogos class (Logos implementation class, used to create BYD car logo)
public class BYDLogos implements Logos{
    
    
    @Override
    public void showLogos() {
    
    
        System.out.println("我的LOGO是 比亚迪");
    }
}

Then we create the factory interface

  • Factory interface Factory
public interface Factory {
    
    
    Car createCar();
    Logos createLogos();
}

In this interface, we declare two interface methods, one for creating vehicles and one for creating car logos, and then each interface that implements the factory must rewrite these two methods

  • BMWFamilyFactory
public class BMWFamilyFactory implements Factory {
    
    
    @Override
    public Car createCar() {
    
    
        return new BMW();
    }

    @Override
    public Logos createLogos() {
    
    
        return new BMWLogos();
    }
}
  • Benz Family Factory Class BenzFamilyFactory
public class BenzFamilyFactory implements Factory{
    
    
    @Override
    public Car createCar() {
    
    
        return new Benz();
    }

    @Override
    public Logos createLogos() {
    
    
        return new BuziLogos();
    }
}
  • BYD family factory class BYDFamilyFactory
public class BYDFamilyFactory implements Factory{
    
    
    @Override
    public Car createCar() {
    
    
        return new BYD();
    }

    @Override
    public Logos createLogos() {
    
    
        return new BYDLogos();
    }
}

If you are careful, you will find that, compared with the above factory method pattern, the name of the factory implementation class here will have one more Family, why?

Because the abstract factory method pattern is used to create a series of instances of products, each specific factory class can only create product objects belonging to its own product family, and product objects of different product families cannot be confused.

  • test class
public class Main {
    
    
    public static void main(String[] args) {
    
    
        //创建奔驰工厂
        Factory benzFamilyFactory = new BenzFamilyFactory();
        benzFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        benzFamilyFactory.createLogos().showLogos();


        BMWFamilyFactory bmwFamilyFactory = new BMWFamilyFactory();
        bmwFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        bmwFamilyFactory.createLogos().showLogos();//创建一辆奔驰LOGO并且显示LOGO

    }
}

operation result

insert image description here

abstract factory patternadvantageThat is, it can guarantee the compatibility between the created product objects. Because each specific factory class can only create product objects belonging to its own product family, there will be no conflicts between product objects of different product families. In addition, the abstract factory pattern also supports adding new product families without modifying existing codes, which conforms to the principle of opening and closing. However, the abstract factory pattern also has someshortcoming. Since the abstract factory interface needs to define a set of methods for creating different product families, when a new product family is added, the abstract factory interface and all its implementation classes need to be modified, which may lead to a certain amount of code modification work.

Summarize

Simple factory pattern:

​ A factory class decides which instance of the product class to create based on the parameters passed in. The simple factory pattern separates the creation and use of objects. The client only needs to pass in parameters to get the required objects without caring about the details of object creation.

Factory method pattern:

​ Define an interface for creating product objects, and subclasses decide which product class to instantiate. The factory method mode delays the creation of objects to subclasses to implement. The client only needs to know the factory class of the required product, and does not need to care about the specific product class.

Abstract factory pattern:

Provides an interface for creating a series of related or interdependent objects without specifying their concrete classes. The abstract factory pattern can be seen as an upgraded version of the factory method pattern, which supports the creation of a set of related product objects. The abstract factory pattern can guarantee the compatibility between the created product objects, but when adding a new product family, the abstract factory interface and all its implementation classes need to be modified.

Simple factory pattern:

advantage:

  1. The factory class contains necessary logical judgments, and can dynamically create related product objects according to the client's request, and the client does not need to know the specific product class.
  2. The simple factory pattern separates the creation and use of objects, and the client only needs to care about the parameters of the required products, and does not need to care about the details of object creation.

shortcoming:

  1. The factory class in the simple factory model has too many responsibilities. Adding new products requires modifying the judgment logic of the factory class, which violates the principle of opening and closing.
  2. The simple factory pattern only supports the creation of one product family and does not support extensions.

Factory method pattern:

advantage:

  1. The factory method pattern delays the creation of objects to subclasses, which conforms to the principle of opening and closing. When adding new products, you only need to add the corresponding factory class.
  2. The factory method pattern supports extensions to create objects of multiple product families.

shortcoming:

  1. The factory method pattern needs to add the corresponding factory class, which increases the complexity of the code.
  2. The factory method pattern increases the abstraction and difficulty of understanding the system.

Abstract factory pattern:

advantage:

  1. The abstract factory pattern can guarantee the compatibility between the created product objects, because each specific factory class can only create product objects belonging to its own product family, and product objects of different product families cannot be confused.
  2. The abstract factory pattern supports the addition of new product families without modifying existing codes, which conforms to the principle of opening and closing.

shortcoming:

  1. The abstract factory pattern needs to add corresponding interfaces and implementation classes, which increases the complexity of the code.
    The single factory mode only supports the creation of one product family and does not support expansion.

Factory method pattern:

advantage:

  1. The factory method pattern delays the creation of objects to subclasses, which conforms to the principle of opening and closing. When adding new products, you only need to add the corresponding factory class.
  2. The factory method pattern supports extensions to create objects of multiple product families.

shortcoming:

  1. The factory method pattern needs to add the corresponding factory class, which increases the complexity of the code.
  2. The factory method pattern increases the abstraction and difficulty of understanding the system.

Abstract factory pattern:

advantage:

  1. The abstract factory pattern can guarantee the compatibility between the created product objects, because each specific factory class can only create product objects belonging to its own product family, and product objects of different product families cannot be confused.
  2. The abstract factory pattern supports the addition of new product families without modifying existing codes, which conforms to the principle of opening and closing.

shortcoming:

  1. The abstract factory pattern needs to add corresponding interfaces and implementation classes, which increases the complexity of the code.
  2. The abstract factory pattern increases the abstraction and difficulty of understanding of the system.

Guess you like

Origin blog.csdn.net/yvge669/article/details/130676295