From our previous article, “Design Patterns: Factory Patterns, Tools for Decoupling,” we gained an in-depth understanding of factory patterns. Today, we continue to introduce a special factory pattern, the Abstract factory pattern.

define

Abstract Factory pattern: Provides an interface to create a series of related or interdependent objects without specifying their concrete classes. Abstract factory mode, also known as Kit mode, belongs to the object creation mode and is the upgraded version of factory method mode. When there are multiple business varieties and business classifications, it is a very good solution to generate the required objects through abstract factory mode.

The Abstract factory pattern contains several roles:

AbstractFactory: A method used to declare the generation of abstract products

ConcreteFactory: A method that implements abstract factory declarations to generate abstract products, generating a set of concrete products that constitute a family of products, each in a product hierarchy;

AbstractProduct: declare interfaces for each product and define abstract business methods for the product in the AbstractProduct;

Product: Defines concrete Product objects produced by concrete factories that implement business methods defined in abstract Product interfaces.

Here’s its generic class diagram:

We can take the operating system as an example. The two most commonly used PC operating systems in the market are Windows and Linux, both of which have common types of components, such as folders, buttons, text, etc. Using the generic class diagram of the abstract factory below, it is not difficult to find that the two systems are equivalent to the product group abstract classes AbstractProductA and AbstractProductB, and the components such as buttons and text are concrete product classes.

Then, if you have one application running on two systems, how do you design it? Is it writing two programs to run on different systems? This is a waste of resources, we can use abstract factory mode to mask the impact of the operating system on the application. The software functions, logic, and UI are all very similar. The only difference is that different factory methods are called and different product classes are used to process the information that interacts with the operating system. This is the advantage of abstract factory.

The code

Now that we know about the generic class diagram of the abstract factory, here is the implementation of the concrete code:

Product family abstract classes, AbstractProductA and AbstractProductB,

Public abstract class AbstractProductA {// Public voidshareMethod() {} // Each product has the same method, different implementation public abstract voiddoSomething();
}
Copy the code
Public abstract class AbstractProductB {// Public voidshareMethod() {} // Each product has the same method, different implementation public abstract voiddoSomething();
}
Copy the code

The concrete implementation class code of the two product families,

public class ProductA1 extends AbstractProductA {
    public void doSomething() {
        System.out.println("I'm product A1"); }}Copy the code
public class ProductA2 extends AbstractProductA {
    public void doSomething() {
        System.out.println("I'm product A2"); }}Copy the code
public class ProductB1 extends AbstractProductB {
    public void doSomething() {
        System.out.println("I'm product B1.");
    }
}
public class ProductB2 extends AbstractProductB {
    public void doSomething() {
        System.out.println("I'm product B2."); }}Copy the code

Abstract factory class AbstractCreator, with N product families, should have N creation methods in an abstract factory class. Here we define product creation for two product families as follows:

Public abstract class AbstractCreator {public abstract AbstractProductA createProductA(); Public abstract AbstractProductB createProductB(); }Copy the code

Then there are the specific factories to create the product. There should be N implementation factory classes for N product classes, and in each implementation factory, the production tasks of different product families are implemented.

public class Creator1 extends AbstractCreator {
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}
public class Creator2 extends AbstractCreator {
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    public AbstractProductB createProductB() {
        returnnew ProductB2(); }}Copy the code

So far, we have created all the roles, and finally designed a scene class to verify whether it can output the information of corresponding products.

Public class Client {public static void main(String[] args) {AbstractCreator creator1 = new creator1 (); AbstractCreator creator2 = new Creator2(); AbstractProductA A1 = creator1.createProducta (); AbstractProductA A2 = creator2.createProducta (); AbstractProductB B1 = creator1.createProductb (); AbstractProductB B2 = creator2.createProductb (); a1.doSomething(); a2.doSomething(); b1.doSomething(); b2.doSomething(); }}Copy the code

The result of the run is:

I'm product A1 and I'm product A2 and I'm product B1 and I'm product B2Copy the code

conclusion

The characteristics of abstract factory mode are summarized. Abstract factory mode is the most abstract and general form among all forms of factory mode. Its advantages and disadvantages are as follows:

1, the generation of concrete classes is isolated, so that customers do not need to know what is created, with good encapsulation.

2. Horizontal scaling is easy. If multiple products need to be added to the same product family, only new factory and product classes need to be added.

3. Vertical expansion is difficult. If you add a new product group, the abstract factory class also adds the corresponding method to create that product group, which would make all the concrete factory classes change, seriously violating the open close principle.

Reference: Zen of Design Patterns