[1] Design mode ~~~Creative mode~~~Simple factory mode (Java)

[Learning Difficulty: ★★☆☆☆, Frequency of Use: ★★★☆☆】

1.1. Pattern Motivation

Consider a simple software application scenario, a software system can provide multiple buttons with different appearances (such as round buttons, rectangular buttons, diamond buttons, etc.), these
buttons are derived from the same base class, but different after inheriting the base class The subclasses of .modify some properties so that they can present different appearances. If we want to use these buttons, we don’t need to know the names of these specific button classes. We only need to know a parameter representing the button class and provide a call Convenient method, pass this parameter into the method to return a corresponding button object, at this time, you can use the simple factory pattern.

1.2. Schema Definition

Simple Factory Pattern: Also known as the Static Factory Method pattern, it belongs to the class creation pattern. In the simple factory pattern, instances of different classes can be returned according to different parameters. The simple factory pattern specifically defines a class to be responsible for creating instances of other classes, and the created instances usually have a common parent class.

1.3. Schema structure

The simple factory pattern contains the following roles:

  • Factory: The factory role factory role is responsible for implementing the internal logic of creating all instances
  • Product: abstract product role The abstract product role is the parent class of all objects created and is responsible for describing the public interface shared by all instances
  • ConcreteProduct: Concrete product role Concrete product role is the creation target, and all created objects act as instances of a specific class of this role.

insert image description here

1.4. Timing diagram

insert image description here

1.5. Code Analysis

1.5.1 Production

package com.zyz;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/8 23:48
 * @Description:Chart接口充当抽象产品类,其子类HistogramChart、PieChart
 *                     和LineChart充当具体产品类,ChartFactory充当工厂类
 */

/**
 * 抽象产品
 */
interface Chart {
    
    
    /**
     * 展示图表
     */
    public void display();
}


/**
 * 柱状图类:具体产品类
 */
class HistogramChart implements Chart {
    
    
    public HistogramChart() {
    
    
        System.out.println("创建柱状图!");
    }

    @Override
    public void display() {
    
    
        System.out.println("显示柱状图");
    }


}

/**
 * 饼状图类:具体产品类
 */
class PieChart implements Chart {
    
    
    public PieChart() {
    
    
        System.out.println("创建饼状图!");
    }

    @Override
    public void display() {
    
    
        System.out.println("显示饼状图!");
    }
}

/**
 * 折线图类:具体产品类
 */
class LineChart implements Chart {
    
    
    public LineChart() {
    
    
        System.out.println("创建折线图!");
    }

    @Override
    public void display() {
    
    
        System.out.println("显示折线图!");
    }
}


/**
 * 图表工厂类:工厂类
 */
class ChartFactory {
    
    
    //静态工厂方法
    public static Chart getChart(String type) {
    
    
        Chart chart = null;
        if (type.equalsIgnoreCase("histogram")) {
    
    
            chart = new HistogramChart();
            System.out.println("初始化设置柱状图!");
        }
        else if (type.equalsIgnoreCase("pie")) {
    
    
            chart = new PieChart();
            System.out.println("初始化设置饼状图!");
        }
        else if (type.equalsIgnoreCase("line")) {
    
    
            chart = new LineChart();
            System.out.println("初始化设置折线图!");
        }
        return chart;
    }
}

1.5.2 Client

package com.zyz;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/8 23:57
 * @Description: 客户端代码
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        Chart chart;

        /**
         * 循环创建
         */
        for (int i = 0; i < 4; i++) {
    
    
            if (i == 0) {
    
    
                //创建柱状图   通过静态工厂方法创建产品
                chart = ChartFactory.getChart("histogram");
                chart.display();
                System.out.println("===============================");
            } else if (i == 1) {
    
    
                //创建饼状图
                chart = ChartFactory.getChart("pie");
                chart.display();
                System.out.println("===============================");
            } else if (i == 2) {
    
    
                //创建折线图
                chart = ChartFactory.getChart("line");
                chart.display();
                System.out.println("===============================");
            } else {
    
    
                //创建折线图
                chart = ChartFactory.getChart("LINE");
                chart.display();
                System.out.println("==============大写的LINE=================");
            }

        }
    }
}

1.5.3 Effect

insert image description here

1.6. Pattern Analysis

  • Separating the creation of objects from the business processing of the objects themselves can reduce the coupling of the system, making both relatively easy to modify.
  • When calling the factory method of the factory class, since the factory method is a static method, it is very convenient to use. It can be called directly through the class name, and only a simple parameter needs to be passed in. In actual development, it can also be used when calling Save the incoming parameters in configuration files in XML and other formats, and there is no need to modify any source code when modifying parameters.
  • The biggest problem with the simple factory model is that the responsibilities of the factory class are relatively heavy. Adding new products requires modifying the judgment logic of the factory class, which is contrary to the principle of opening and closing.
  • The point of the simple factory pattern is: when you need something, you only need to pass in a correct parameter to get the object you need without knowing the details of its creation.

1.7. Examples

(Omitted) Same as 1.5

1.8. Advantages of Simple Factory Pattern

  • The factory class contains the necessary judgment logic, which can decide when to create an instance of the product class, and the client can exempt from the responsibility of directly creating product objects, and only "consume" the product; the simple factory model realizes the responsibility of Segmentation, which provides specialized factory classes for creating objects.
  • The client does not need to know the class name of the specific product class created, but only needs to know the parameters corresponding to the specific product class. For some complex class names, the user's memory can be reduced through the simple factory model.
  • By introducing configuration files, it is possible to replace and add new specific product categories without modifying any client code, which improves the flexibility of the system to a certain extent.
    1.9. Disadvantages of the simple factory pattern
  • Since the factory class centralizes all product creation logic, once it fails to work properly, the entire system will be affected.
  • Using the simple factory pattern will increase the number of classes in the system, and increase the complexity and difficulty of understanding the system in a certain program.
  • It is difficult to expand the system. Once a new product is added, the factory logic has to be modified. When there are many types of products, the factory logic may be too complicated, which is not conducive to system expansion and maintenance.
  • Due to the use of static factory methods in the simple factory pattern, factory roles cannot form an inheritance-based hierarchical structure.

1.10. Applicable environment

The simple factory pattern can be used in the following situations:

  • The factory class is responsible for creating fewer objects: Since there are fewer objects created, the business logic in the factory method will not be too complicated.
  • The client only knows the parameters passed into the factory class, and does not care about how to create the object: the client does not need to care about the details of creation, or even remember the class name, but only needs to know the parameters corresponding to the type.

1.11. Pattern application

  1. The simple factory pattern is widely used in the JDK class library, such as the tool class java.text.DateFormat, which is used to format a local date or time.
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Localelocale);
  1. Java Cryptography
    Get key generators for different encryption algorithms:
KeyGenerator keyGen=KeyGenerator.getInstance("DESede"); 

Create a cipher:

Cipher cp=Cipher.getInstance("DESede");

1.12. Summary

  • The creational pattern abstracts the instantiation process of the class, and can separate the creation of the object from the use of the object.
  • The simple factory pattern is also known as the static factory method pattern, which belongs to the class creation pattern. In the simple factory pattern, instances of different classes can be returned according to different parameters. The simple factory pattern specifically defines a class to be responsible for creating instances of other classes, and the created instances usually have a common parent class.
  • The simple factory pattern includes three roles: the factory role is responsible for implementing the internal logic of creating all instances; the abstract product role is the parent class of all objects created, and is responsible for describing the common interface shared by all instances; the specific product role is the creation target, and all The objects created act as instances of a concrete class for this role.
  • The point of the simple factory pattern is: when you need something, you only need to pass in a correct parameter to get the object you need without knowing the details of its creation.
  • The biggest advantage of the simple factory model is that it realizes the separation of object creation and object use, and assigns the creation of objects to a special factory class. However, its biggest disadvantage is that the factory class is not flexible enough. Adding new specific products requires modifying the factory class. Judgment logic code, and when there are many products, the factory method code will be very complicated.
  • The application of the simple factory pattern includes: the factory class is responsible for creating fewer objects; the client only knows the parameters passed into the factory class, and does not care about how to create objects.

1.13 Extension (configuration file read parameters)

We can store the parameters of the static factory method in a configuration file in XML or properties format, as shown in config.xml below:

<?xml version="1.0"?>
<config>
    <chartType>histogram</chartType>
</config>

Then use a tool class XMLUtil to read the string parameters in the configuration file. The code of the XMLUtil class is as follows:

package com.zyz.config;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/9 0:33
 * @Description:
 */
public class XMLUtil {
    
    
    /**
     * 该方法用于从XML配置文件中提取图表类型,并返回类型名
     * @return
     */
    public static String getChartType() {
    
    
        String path = "F:\\java学习资料(后端)\\github管理后端学习资料\\后端学习\\设计模式\\代码\\DesignPatterns-Java-Examples\\简单工厂模式\\src\\main\\resources\\config.xml";
        try {
    
    
            //创建文档对象
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File(path));

            //获取包含图表类型的文本节点
            NodeList nl = doc.getElementsByTagName("chartType");
            Node classNode = nl.item(0).getFirstChild();
            String chartType = classNode.getNodeValue().trim();
            return chartType;
        }
        catch(Exception e) {
    
    
            e.printStackTrace();
            return null;
        }
    }
}

After introducing the configuration file and the tool class XMLUtil, the client code is modified as follows:

package com.zyz;

import com.zyz.config.XMLUtil;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/9 0:34
 * @Description: 通过读取xml配置文件,来完成对象创建
 */
public class Client2 {
    
    
    public static void main(String[] args) {
    
    
        Chart chart;
        //读取配置文件中的参数
        String type = XMLUtil.getChartType();
        //创建产品对象
        chart = ChartFactory.getChart(type);
        chart.display();
    }
}

It is not difficult to find that the above client code does not contain any information related to the specific chart object. If you need to change the specific chart object, you only need to modify the configuration file config.xml without modifying any source code, which conforms to the "open and close principle".

insert image description here

Guess you like

Origin blog.csdn.net/weixin_43304253/article/details/130628620