Detailed abstract factory pattern

1. Introduction

Abstract Factory Pattern (Abstract Factory Pattern) is also a creational design pattern, which provides a factory interface (super factory) that creates a series of related or dependent objects. Different types of factories then implement this abstract factory, and finally A factory creator class can be provided to create specific factories by passing in factory type parameters. It is an extension of the factory method pattern . The core idea is to abstract the factory itself. Its main purpose is to create other factories around a super factory or central factory. This super factory is also called the factory of other factories.

The difference between it and the factory method pattern is that the factory method pattern is aimed at a product level; while the abstract factory pattern is aimed at multiple product levels, that is, a product family. In programming, usually a product level is represented as an interface or abstract class and its implementation class, that is to say, all products provided by the factory method pattern are derived from the same interface or abstract class, and the abstract factory pattern The products provided are derived from different interfaces or abstract classes.

The so-called product family refers to a family composed of functionally related products located in different product levels. A series of products provided by the abstract factory pattern form a product family; and a series of products provided by the factory method form a product level.

Compared with real life, a product family, such as digital products. One product class, such as mobile phones, includes all brands of mobile phones belong to this product class, and all notebook computers belong to another product class. All mobile phones and computers together constitute the product family of digital products.

design principle

The abstract factory pattern usually contains four required roles and one optional role:

  • Abstract Factory (Abstract Factory): Define an interface or abstract class that declares a set of methods for creating related product objects. The return value of these methods is usually an abstract product.
  • Concrete Factory: It implements the method of creating product objects declared in the abstract factory, and creates a specific product object according to different product parameters at the same product level.
  • Abstract Product (Abstract Product): Define an interface or abstract class to represent similar products, and declare the methods that the product has in the abstract product.
  • Concrete Product: It defines the specific products owned by the abstract product, and implements the business methods defined in the abstract product interface.
  • Factory Creator (optional role): Provide a static method to create a specific factory class according to different factory type parameters passed in, and the return value is received by the abstract factory.

UML class diagram
insert image description here

Scalability Analysis

Tip: Many articles write about extending a product family. I don’t quite understand this statement. The abstract factory pattern corresponds to only one product family. I think it should be a question of Chinese comprehension. It can only be said to expand a product family, not a product family. The former means that I want to add a product level under a product family, and the latter means that I want to add a brand new product. family, this is not an expansion, but a new start. This is how I understand it, and everyone is welcome to question it.

extend a product

A specific product needs to be expanded. At the same time, modify part of the code of the specific factory layer. A small violation of the open-closed principle.

Extend a product class

Both the abstract product layer and the concrete product layer need to be extended. It is also necessary to modify the top-level abstract factory layer to add additional creation methods, which will cause all concrete factory implementations to be modified synchronously, which is very troublesome and greatly violates the principle of opening and closing.

advantage

  • Separating the creation and use of products makes the client code more concise and hides the details of product creation from the client.
  • Unify the creation of a series of related product objects into an abstract factory, the client only needs to access the abstract factory, and the specific product factory can be flexibly replaced.
  • When multiple objects in a family are designed to work together, it guarantees that clients will always only use objects from the same family.

shortcoming

  • It is very difficult to add a new product level under a product family. It even needs to modify the abstraction layer code and all the implementations under it, which seriously violates the "open-closed principle".
  • It increases the complexity of the code, increases the abstraction of the system, and increases the difficulty of understanding.

Applicable scene

  • A system requires a series of related or interdependent product objects, and the implementation of these product objects may change over time.
  • The system needs to dynamically select one of a product family at runtime, rather than a single product.
  • The system needs to ensure that a set of product objects are designed to be used together, not individually.
  • The system needs to provide a unified access interface for different products of a product family, regardless of the specific implementation of the product.

2. Realization case

Simulate a product family, which includes two product levels of "shape" and "color", and provide corresponding creation methods.

1. Abstract product layer and concrete product layer representing "shape"

Tip: Note that here is an interface and two implementation classes, which are jointly defined in a Shape.java file. The same below.

public interface Shape {
    
    
    void draw();
}

class Square implements Shape{
    
    
    @Override
    public void draw() {
    
    
        System.out.println("我是正方形");
    } 
}

class Circle implements Shape{
    
    
    @Override
    public void draw() {
    
    
        System.out.println("我是圆形");
    }
}

2. Abstract product layer and concrete product layer representing "color"

public interface Color {
    
    
    void fill();
}

class Red implements Color{
    
    
    @Override
    public void fill() {
    
    
        System.out.println("我是红色");
    }   
}

class Blue implements Color{
    
    
    @Override
    public void fill() {
    
    
        System.out.println("我是蓝色");
    }  
}

3. Abstract factory and concrete factory layer

//抽象工厂类
public interface AbstractFactory {
    
    
    Shape getShape(String shape);
    Color getColor(String color);
}
//形状工厂类
class ShapeFactory implements AbstractFactory {
    
    
    @Override
    public Shape getShape(String shape){
    
          
       if("square".equalsIgnoreCase(shape)){
    
    
          return new Square();
       } else if("circle".equalsIgnoreCase(shape)){
    
    
          return new Circle();
       }else{
    
    
            return null;
       }
    }
    @Override
    public Color getColor(String color) {
    
    
       return null;
    }
 }
//颜色工厂类
 class ColorFactory implements AbstractFactory {
    
    
    @Override
    public Shape getShape(String shape){
    
          
        return null;
    }
    @Override
    public Color getColor(String color) {
    
    
        if("red".equalsIgnoreCase(color)){
    
    
            return new Red();
         } else if("blue".equalsIgnoreCase(color)){
    
    
            return new Blue();
         }else{
    
    
            return null;
         }
     }
 }

5. Factory Creator

public class FactoryProducer {
    
    
    //工厂创造器
    public static AbstractFactory createFactory(String choice){
    
    
        if("shape".equalsIgnoreCase(choice)){
    
    
           return new ShapeFactory();
        } else if("color".equalsIgnoreCase(choice)){
    
    
           return new ColorFactory();
        }else{
    
    
            return null;
        }
     }
}

6. Test class

public class Test {
    
    
    public static void main(String[] args) {
    
    
        //测试形状工厂
        AbstractFactory absFactory01=FactoryProducer.createFactory("shape");
        absFactory01.getShape("circle").draw();

        //测试颜色工厂
        AbstractFactory absFactory02=FactoryProducer.createFactory("color");
        absFactory02.getColor("red").fill();

        //不使用工厂创造器,直接new的形式
        AbstractFactory absFactory03=new ColorFactory();
        absFactory03.getColor("blue").fill();
    }
}

Example of running results:

image-20230430141636899

3. Summary

Well, dear readers and friends, thank you for your hard work. After studying this blog post, I believe you have a very deep understanding of the abstract factory model. Compared with the factory method mode, this mode is indeed more complicated and difficult to master. This article tries to explain the design principle, scalability, advantages and disadvantages of the abstract factory mode in an easy-to-understand form. I hope everyone can understand its usage carefully in combination with the case. Questions are welcome to comment.


Creation is not easy. If this article is helpful to you, please like, bookmark and pay attention. Your support and encouragement are the biggest motivation for my creation.

Guess you like

Origin blog.csdn.net/qq_36756227/article/details/130450108