Software Design patterns, also known as Design patterns, are summaries of code Design experiences that have been repeatedly used and known by most people through classification and cataloguing

It describes some recurring problems in the software design process, and the solution to the problem. That is to say, it is a series of routines to solve specific problems, is the summary of predecessors’ code design experience, has a certain universality, can be used repeatedly.

Its purpose is to improve code reusability, code readability, and code reliability.

Section factory pattern in the last chapter (on) – the factory method pattern we specifically to learn the factory method pattern, but we know that the factory method pattern considering is a kind of production, but in real life many factory is a comprehensive factory, can produce many grade (species) of products, such as farm animals and plants, Electrical factory produces both TV sets and washing machines or air conditioners, and university has both software majors and biology majors, etc. Under such circumstances, it is no longer appropriate for us to use the factory method mode for design, but we need another factory mode – abstract factory mode.

Abstract factory pattern is mainly used to solve the production of multiple types of products

So what is the abstract factory pattern?

The definition of AbstractFactory pattern is a pattern structure that provides an interface for the visiting class to create a set of related or interdependent objects, and the visiting class can get different levels of products of the same family without specifying the specific class of the products it wants. Here two concepts arise: family and same level.

Our electrical production factory is as follows:

Fig. 1 Product grade and product family of electrical appliance factory

By comparing the previous factory method pattern, we can see that the abstract factory pattern is an updated version of the factory method pattern. The factory method pattern only produces one level of products, while the abstract factory pattern can produce multiple levels of products

To use the abstract factory pattern, the following conditions must be met:

  • There are multiple product families in the system, each specific factory creates the same family but belongs to different hierarchical structure of products.
  • The system can only consume one family of products at a time, that is, the products of the same family can be used together.

As an updated version of Factory Method Pattern, Abstract Factory Pattern is composed of abstract factory, concrete factory, abstract product and concrete product, but the number of abstract products varies with the number of methods in the abstract factory.

  • Abstract Factory: Provides an interface to create a product. It contains multiple product-creation methods, newProduct(), which can create multiple products of different levels.
  • Concrete Factory: It mainly realizes multiple abstract methods in the abstract Factory to complete the creation of specific products.
  • Abstract Product: Defines the specification of the Product and describes the main features and functions of the Product. The Abstract Factory pattern has multiple abstract products.
  • ConcreteProduct: Implements the interface defined by the abstract product role, created by the concrete factory, and has a many-to-one relationship with the concrete factory.

The structure drawing is as follows:

How does the code do that?

For example, we now have a need to have two farms, the first farm for cattle and vegetables, the second farm for horses and fruit. After analysis, we produce different types of products. The factory method mode can only complete the production of the same series of products, but if we need to produce different series of products, we need to use the abstract factory mode

The code is as follows:

/** * @author Hz * @version 1.0 */ public class FarmTest {public static void main(String[] args) {try {Farm f; Animal a; Plant p; F = (Farm) ReadXML.getObject(); // ReadXML.getObject(); a = f.newAnimal(); p = f.newPlant(); a.show(); p.show(); } catch (Exception e) { System.out.println(e.getMessage()); Public void show();} public void show(); } class Horse implements Animal {public Horse() {System.out.println();} class Horse implements Animal {public Horse() {System.out.println(); } public void show() {System.out.println();} public void show() {System.out.println(); } class class implements Animal {public class () {System.out.println(" class ());} class (); class (); class (); } public void show() {System.out.println();} public void show() {System.out.println(); Public void show(); public void show(); } // class Fruitage implements Plant {public Fruitage() {system.out.println (" Fruitage class generation "); } public void show() {System.out.println();} public void show() {System.out.println(); }} // Class Vegetables implements Plant {public Vegetables() {System.out.println(" ");} // Class Vegetables implements Plant {public Vegetables() {System.out.println(") "); } public void show() {System.out.println();} public void show() {System.out.println(); Public Animal Newanimal ();} public Animal Newanimal (); public Plant newPlant(); } // Class 1 SgFarm implements Farm {public Animal Newanimal () {System.out.println(" New cow is new! ");} // Class 1 SgFarm implements Farm {public Animal Newanimal () {System.out.println(" New cow is new! "); ); return new Cattle(); } public Plant newPlant() {System.out.println();} public Plant newPlant() {System.out.println(); ); return new Vegetables(); }} // 2 class srFarm implements Farm {public Animal Newanimal () {System.out.println(" New Horse is not implemented! ");} // 2 class srFarm implements Farm {public Animal Newanimal () {System.out.println(" New Horse is not implemented! "); ); return new Horse(); } public Plant newPlant() {System.out.println(" Fruit grows! "); ); return new Fruitage(); }}
import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.File; /** * @author Hz * @version 1.0 */ public class ReadXML2 {public static Object getObject() {try { DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("src/AbstractFactory/config.xml")); NodeList nl = doc.getElementsByTagName("className"); Node classNode = nl.item(0).getFirstChild(); String cName = "AbstractFactory." + classNode.getNodeValue(); System.out.println(" New class name: "+ CNAME); Class<? > c = Class.forName(cName); Object obj = c.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); return null; }}}

So what are the advantages of this model?

The abstract factory pattern is optimized over the factory method pattern. All factory method patterns have the advantages of

In addition, it also has its own advantages:
  • 1. It is possible to manage the related multi-level products in the product family within the class, without the need to introduce multiple new classes for management.
  • 2. When a product family is needed, an abstract factory ensures that clients always use only product groups of the same product.
  • 3. The abstract factory enhances the extensibility of the program. When a new product family is added, there is no need to modify the original code to meet the Open Closed Principle.
Disadvantages:

All factory classes need to be modified when a new product is added to the product family. It increases the abstractness and difficulty of understanding the system.

Based on the above analysis of the abstract factory pattern, we can see that the abstract factory pattern is generally applicable to the following scenarios:

  • When the objects to be created are a series of interrelated or interdependent product families, such as television sets, washing machines, air conditioners in an electrical factory, etc.
  • There are multiple product families in the system, but only one family of products is used at a time. For example, some people only like to wear a certain brand of clothes and shoes.
  • The product class library is provided in the system, and the interface of all products is the same, and the client does not depend on the creation details and internal structure of product instances.

Conclusion:

The extension of the abstract factory pattern has a certain “Open Closed Principle” bias:

  • When adding a new product family, it only needs to add a new specific factory, without modifying the original code, which meets the open and close principle.
  • When a new type of product needs to be added to the product family, all the factory classes need to be modified, which does not meet the Open Closed Principle.

On the other hand, when there is only one hierarchical structure of products in the system, the abstract factory mode will degenerate to the factory method mode. Factory mode is used in many occasions in real life, and the concrete use of factory method mode or abstract factory mode depends on our actual situation.