The role of the [factory pattern] of the java design pattern

During the teaching and promotion of design patterns, many corporate and school students often ask me what is the use of factory patterns (including simple factory patterns, factory method patterns and abstract factory patterns). Flexibility to create objects, and factories for Mao? Smile, in this article I will briefly talk about the role of factories around creating and using objects.

      There are usually three categories of responsibilities associated with an object: responsibilities that the object itself has, responsibilities that create objects, and responsibilities that use objects . The responsibility of the object itself is relatively easy to understand, that is, some data and behaviors of the object itself can be realized through some public methods. In this article, we will briefly discuss object creation responsibilities and usage responsibilities.

      In the Java language, we usually have the following ways to create objects:

       (1)  Use the new keyword to create objects directly;

       (2)  Create objects through reflection mechanisms;

       (3)  Create an object through the clone() method;

       (4)  Create objects through factory classes.

     There is no doubt that using the new keyword  directly in the client code is the easiest way to create an object, but it is less flexible. Let's illustrate it with a simple example: 

[java]  view plain copy  
  1. class LoginAction {  
  2.     private  UserDAO married;  
  3.       
  4.     public LoginAction() {  
  5.         udao =  new  JDBCUserDAO();  //Create object  
  6.     }  
  7.       
  8.     publicvoid execute() {   
  9.         //other code  
  10.         udao.findUserById();  //Use object  
  11.         //other code  
  12.     }  
  13. }  

      In the LoginAction class, an object udao of type UserDAO is defined , a udao object of type JDBCUserDAO is created in the constructor of LoginAction , and the findUserById ( ) method of the udao object is called in the execute() method. no problem. Let's analyze the relationship between LoginAction and UserDAO . The LoginAction class is responsible for creating an object of a UserDAO subclass and using UserDAO methods to complete the corresponding business processing. That is to say, LoginAction is responsible for both the creation of udao and the use of udao. , the responsibilities of creating objects and using objects are coupled together. This design will lead to a serious problem: if you want to be able to use another subclass of UserDAO in LoginAction such asFor objects of type HibernateUserDAO , the source code of the LoginAction class must be modified , which violates the "open-closed principle". How to solve this problem?

      One of the most common solutions is to remove the udao object creation responsibility from the LoginAction class, and create the object outside the LoginAction class, so who is responsible for creating the UserDAO object? The answer is: the factory class. By introducing the factory class, the client class (such as LoginAction) does not involve the creation of the object, and the creator of the object does not involve the use of the object. The structure after the introduction of the factory class UserDAOFactory is shown in Figure 1:

Figure Structure diagram after the introduction of the factory class

       The introduction of the factory class will reduce the maintenance workload due to changes in the product or factory class. If the constructor of a subclass of UserDAO changes or needs to add or remove different subclasses, just maintain the code of UserDAOFactory without affecting the LoginAction ; if the interface of UserDAO changes, such as adding, removing methods or Change the method name, only need to modify the LoginAction , it will not bring any impact to UserDAOFactory .

       在所有的工厂模式中,我们都强调一点:两个类AB之间的关系应该仅仅是A创建B或是A使用B,而不能两种关系都有。将对象的创建和使用分离,也使得系统更加符合“单一职责原则”,有利于对功能的复用和系统的维护。

       此外,将对象的创建和使用分离还有一个好处:防止用来实例化一个类的数据和代码在多个类中到处都是,可以将有关创建的知识搬移到一个工厂类中,这在Joshua Kerievsky的《重构与模式》一书中有专门的一节来进行介绍。因为有时候我们创建一个对象不只是简单调用其构造函数,还需要设置一些参数,可能还需要配置环境,如果将这些代码散落在每一个创建对象的客户类中,势必会出现代码重复、创建蔓延的问题,而这些客户类其实无须承担对象的创建工作,它们只需使用已创建好的对象就可以了。此时,可以引入工厂类来封装对象的创建逻辑和客户代码的实例化/配置选项。

      使用工厂类还有一个“不是特别明显的”优点,一个类可能拥有多个构造函数,而在JavaC#等语言中构造函数名字都与类名相同,客户端只能通过传入不同的参数来调用不同的构造函数创建对象,从构造函数和参数列表中也许大家根本不了解不同构造函数所构造的产品的差异。但如果将对象的创建过程封装在工厂类中,我们可以提供一系列名字完全不同的工厂方法,每一个工厂方法对应一个构造函数,客户端可以以一种更加可读、易懂的方式来创建对象,而且,从一组工厂方法中选择一个意义明确的工厂方法,比从一组名称相同参数不同的构造函数中选择一个构造函数要方便很多。如图2所示:

        在图2中,矩形工厂类RectangleFactory提供了两个工厂方法createRectangle()createSquare(),一个用于创建长方形,一个用于创建正方形,这两个方法比直接通过构造函数来创建长方形或正方形对象意义更加明确,也在一定程度上降低了客户端调用时出错的概率。

      So, one might ask, is it necessary to have a factory class for every class in the design? The answer is: a case-by-case analysis. If the product class is very simple, there are not too many variables, and the construction process is also very simple, there is no need to provide a factory class for it, and it can be instantiated directly before use, such as the String class in the Java language , we do not need to provide a factory class for it. It specifically provides a StringFactory , which is a bit like using a knife to kill a chicken, and it will lead to flooding of factories and increase the complexity of the system.


https://blog.csdn.net/lovelion/article/details/7523392

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326023719&siteId=291194637