Factory method model

Posted by warstormer on Tue, 18 Jan 2022 09:16:58 +0100

The simple factory mode violates the opening and closing principle, and the "factory method mode" is a further abstraction of the simple factory mode. Its advantage is that the system can introduce new products without modifying the original code, that is, meet the opening and closing principle.

advantage:

  • Users only need to know the name of the specific factory to get the desired product, without knowing the specific creation process of the product.
  • Flexibility is enhanced. For the creation of new products, you only need to write one more corresponding factory class.
  • Typical decoupling framework. The high-level module only needs to know the abstract class of the product, does not need to care about other implementation classes, and meets the Demeter rule, dependency inversion principle and Richter substitution principle.

Disadvantages:

  • The number of classes is easy to be too many, which increases the complexity
  • It increases the abstraction and understanding difficulty of the system
  • Abstract products can only produce one product, which can be used Abstract factory pattern solve.

Application scenario:

  • The customer only knows the name of the factory that created the product, but does not know the specific product name. Such as TCL TV factory, Hisense TV factory, etc.
  • The task of creating objects is completed by one of multiple concrete sub factories, while the abstract factory only provides the interface to create products.
  • Customers don't care about the details of creating products, they only care about the brand of products

Structure and implementation of pattern

The factory method pattern consists of four elements: abstract factory, concrete factory, abstract product and concrete product. This section analyzes its basic structure and implementation method.

1. Structure of the model

The main roles of the factory method pattern are as follows.

  1. Abstract Factory: it provides an interface for creating products, through which the caller accesses the factory method newProduct() of a specific factory to create products.
  2. Concrete factory: it mainly implements the abstract methods in the abstract factory and completes the creation of specific products.
  3. Abstract Product: it defines the specification of the Product and describes the main characteristics and functions of the Product.
  4. Concrete product: it implements the interface defined by the abstract product role, which is created by the specific factory and corresponds to the specific factory one by one.

Its structure is shown in Figure 1.

2. Implementation of mode

Write the code of this mode according to figure 1 as follows:

public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product a;
            AbstractFactory af;
            af = (AbstractFactory) ReadXML1.getObject();
            a = af.newProduct();
            a.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
//Abstract product: provides the interface of the product
interface Product {
    public void show();
}
//Concrete product 1: implement abstract methods in abstract products
class ConcreteProduct1 implements Product {
    @Override
    public void show() {
        System.out.println("Specific product 1 display...");
    }
}
//Concrete product 2: implement abstract methods in abstract products
class ConcreteProduct2 implements Product {
    @Override
    public void show() {
        System.out.println("Specific product 2 display...");
    }
}
//Abstract factory: provides the generation method of factory products
interface AbstractFactory {
    public Product newProduct();
}
//Specific factory 1: the generation method of factory products is realized
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public Product newProduct() {
        System.out.println("Specific factory 1 generation-->Specific products 1...");
        return new ConcreteProduct1();
    }
}
//Specific factory 2: the generation method of factory products is realized
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public Product newProduct() {
        System.out.println("Specific plant 2 generation-->Specific products 2...");
        return new ConcreteProduct2();
    }
}

class ReadXML1 {
    //This method is used to extract the specific class name from the XML configuration file and return an instance object
    public static Object getObject() {
        try {
            //Create document object
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File("src/FactoryMethod/config1.xml"));
            //Gets the text node containing the class name
            NodeList nl = doc.getElementsByTagName("className");
            Node classNode = nl.item(0).getFirstChild();
            String cName = "FactoryMethod." + classNode.getNodeValue();
            //System.out.println("new class name:" + cName);
            //Generate an instance object from the class name and return it
            Class<?> c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}