Abstract Factory belongs to the creation pattern. In order of abstraction, the Factory pattern can be divided into simple Factory pattern -> Factory pattern -> Abstract Factory pattern.

intentions

Provides an interface to create a series of related or interdependent objects without specifying their concrete classes.

For example,

The car factory

We all know that cars have many parts, and with the division of labor brought about by the industrial Revolution, many parts can be easily replaced. But in real life, we consumers do not want to do this. We want to buy BMWS that contain parts of the same series to ensure maximum matching, thus bringing better performance and comfort.

So consumers don’t want to go to the tyre factory, the steering wheel factory, the window factory to buy, but instead send their demands to the BMW factory, an abstract factory that assembles them. Then you are the boss of this factory. It is known that the components of a car are fixed, but different parts have different models from different manufacturers. You need to launch several different combinations of models to meet the needs of consumers at different prices.

Maze game

You make a maze game, the known elements are room, door, wall, their combination relationship is fixed, you generate a random maze through a set of algorithms, this algorithm calls the factory of room, door, wall to generate corresponding instances. But with the release of the expansion, you will need to generate rooms with new features (which can regenerate health), doors with new features (which require magic keys to open), walls with new features (which can be destroyed by bombs), and modifying the existing maze generation algorithm will violate the open and close principle (which requires modification on existing objects). If you wanted the algorithm that generated the maze to be completely unaware of the new material, how would you design it?

Event linkage

Suppose we build a front-end build engine, and now we want to build an association mechanism so that clicking on a table component cell will pop up a modal box with a line chart inside. It is known that the business side has the need to customize the table component, modal box component, line chart component, but the linkage relationship between components is determined, how will you design?

Intention to explain

In the case of a car factory, we know the components of a car, and in order to assemble a car, the components need to be assembled in a certain way, and the specific components need to be scalable.

In the example of a maze game, we know that the components of a maze are rooms, doors, and walls. In order to generate a maze, we need to generate many instances of rooms, doors, and walls by some algorithm, and the specific use of which rooms, which doors, and which walls is the algorithm does not care, but needs to be expanded.

In event of example, we know this form the pop-up trend chart of basic component interaction scenarios is form components, modal frame components, line chart component, need to be some kind of linkage mechanism for the relationship between them, and what is the specific form, modal frame components, what line chart component is, you don’t care about this event linkage is needed can be expanded, Tables can be replaced with any registered table of any business party, as long as the onClick mechanism is satisfied.

Intent: Provide an interface to create a series of related or interdependent objects without specifying their concrete classes.

Don’t these three examples fit the above purpose? The abstract factory we want to design is to create a series of related or interdependent objects, in the above example, the components of the car, the materials of the maze game, and the components of the event linkage. We don’t have to specify their classes, which means we don’t care what brand the steering wheel is, whether the maze room is a normal room, whether the linkage line is drawn by Echarts, we just have to describe the relationship between them, and the good thing about that is, In the future, when we expand with new steering wheels, new rooms, new line charts, we don’t need to modify the abstract factory.

The code example

class AbstractFactory {
  createProducts(concreteFactory: ConcreteFactory) {
    const productA = concreteFactory.createProductA();
    const productB = concreteFactory.createProductB();

    // Establish A fixed association between A and B, even if the implementation of A and B is changed to any implementationproductA.bind(productB); }}Copy the code

ProductA. Bind (productB) is an abstract representation:

  • For the automobile factory example, represents the process of assembling the automobile.
  • For the maze game example, the process of generating a maze.
  • For the event linkage example, the process of creating associations between components.

Suppose we have two sets of ConcreteFactoryA and Magic ConcreteFactoryB in our maze, and call createProducts to ConcreteFactoryA and Magic ConcreteFactoryB. The output is a maze built by ordinary materials, the input is magic materials, the output is a maze built by magic materials.

Labyrinth when we want to create a set of new materials, such as lava maze, as long as we create a set of molten material (room, lava door, lava wall), put a ConcreteFactoryC molten material generated factory passed to AbstractFactory. CreateProducts can.

We can find that using the abstract factory mode, we can easily expand new materials, such as a new set of auto parts, a new set of maze materials, a new set of event linkage components, this process only needs to create a new class, no need to modify any classes, in line with the open and closed principle.

disadvantages

Every design pattern has its own scenarios, which in turn show that there are some scenarios where it doesn’t work.

Again, if instead of extending a new wheel, wall, or line chart, we need to:

  • The car factory is adding a new component to the car: autopilot.
  • Maze game to add a new feature material: trap.
  • Add a detailed trend statistics table for event linkage.

You see, instead of adding a new set of implementations for existing elements, implementing new elements can be very complicated, because not only do we need to add each new element to all the ConcreteFactories, but we also need to modify the abstract factory to link the new element to the old one, violating the open and close principle.

Therefore, for systems with fixed elements, it is appropriate to use abstract factories, but not vice versa.