Java common design pattern - factory pattern

Introduction:

Factory Pattern is one of the most commonly used design patterns in Java, also known as polymorphic factory pattern and virtual constructor pattern. Belongs to the creation mode.

In the factory pattern, we do not expose the creation logic to the client when creating the object, and we use a common interface to point to the newly created object.

main function:

The instantiation of the class (creation of specific products) is delayed to the subclass (concrete factory) of the factory class, that is, the subclass decides which class should be instantiated.

Application scenarios:

1. It is impossible to foresee at the time of coding what kind of instance of the class is created.

2. The system should not depend on the details of how product class instances are created, composed, and expressed.

Solve the problem:

In the simple factory pattern, there is an important defect: once the factory needs to produce new products, the method logic of the factory class needs to be modified, which violates the OCP principle (Open Closed Principle). Therefore, in order to solve this problem, the factory method pattern defers the creation of specific products to the subclasses of the factory class (concrete factories). At this time, the factory class is no longer responsible for the creation of all products, but only gives the interfaces that the specific factories must implement. , so that the factory method pattern does not modify the factory class logic but adds a new factory subclass when adding a new product, which conforms to the open-closed principle and overcomes the shortcomings of the simple factory pattern.

Implementation steps:

Step 1: Create a product interface

package design.pattern.factory1;
/**
 * Abstract product categories
 * <br>类名:Car<br>
 * Author: mht<br>
 * Date: March 20, 2018 - 11:41:50 PM<br>
 */
public interface Car {
    /** run*/
    public void run();
    /** Drift */
    public void dift();
    
}

Step 2: Create specific product categories according to business needs: product A, product B, and product interface

package design.pattern.factory1;

/**
 * Truck class: The specific car class that implements the car interface
 * <br>类名:Truck<br>
 * Author: mht<br>
 * Date: March 20, 2018 - 11:45:03 PM<br>
 */
public class Truck implements Car{

    @Override
    public void run() {
        System.out.println("Truck runs...");
    }

    @Override
    public void dift() {
        System.out.println("Truck drifting...don't die...");
    }

}
package design.pattern.factory1;

/**
 * Bus: The specific vehicle type that realizes the vehicle type
 * <br>类名:Bus<br>
 * Author: mht<br>
 * Date: March 21, 2018 - 8:24:19am<br>
 */
public class Bus implements Car{

    @Override
    public void run() {
        System.out.println("The bus runs...");
    }

    @Override
    public void dift() {
        System.out.println("The bus drifts... do not die!");
    }

}
package design.pattern.factory1;

/**
 * Car: A specific vehicle class that realizes the cycling class
 * <br>类名:Sedan<br>
 * Author: mht<br>
 * Date: March 21, 2018 - 8:24:55am<br>
 */
public class Sedan implements Car{

    @Override
    public void run() {
        System.out.println("Car runs...");
    }

    @Override
    public void dift() {
        System.out.println("Car drifting...easier...");
    }

}

Step 3: Create a Factory Class

Note here that some people will create a factory interface separately, and then create a specific factory implementation class, each specific factory will have a method for returning a specific product, and the naming is also consistent with the specific product class, such as: factory A (implementation of factory interface) - (production) product A; factory B - product B... I think this method is too awkward to implement, and the factory class belongs to the intermediate class, so it does not need to be matched with each product , which in turn causes the number of classes in the project to increase in pairs while producing new products . The following is another convenient implementation of the factory class:

package design.pattern.factory1;

public class CarFactory {

    /**
     * How to get car<br>
     * Author: mht<br>
     * Time: March 20, 2018 - 11:52:54 pm<br>
     */
    public static Car getCar(Class c) {
        if (c == null)
            return null;
        try {
            /**
             * Through the newInstance() method, the abstraction of the factory class can be avoided, and the production process can be separated from the class information of the product<br>
             * Make the factory class "generalized". Separate abstract factory class, and then use the original method of new when producing products, <br>
             * The factory class corresponding to the specific product needs to be extended additionally, and this newInstance() method actually simplifies this complexity, <br>
             * But it also solves the problem that new products need to modify the factory class logic.
             */
            Car car = (Car) Class.forName(c.getName()).newInstance();
            return car;
        } catch (Exception e) {
            e.printStackTrace ();
        }

        return null;
    }
}


The above three steps have achieved the realization of the factory method pattern. Let's take a simple test of the main method to see the effect:

package design.pattern.factory1;

public class testFactoryPattern {

    public static void main(String[] args) {
        Car bus = CarFactory.getCar(Bus.class);
        bus.run();
        bus.dift();
        Car truck = CarFactory.getCar(Truck.class);
        truck.run();
        truck.dift();
        Car sedan = CarFactory.getCar (Sedan.class);
        sedan.run();
        sedan.dift ();
    }
}
operation result:
The bus runs...
The bus drifts... don't die!
truck run...
Truck Drift... Don't Die...
sedan run...
Sedan Drift... Easier...

Understanding of the factory pattern:

The factory pattern takes full advantage of inheritance and polymorphism in the Java language. By analyzing the commonalities between product A and product B or product C, an appropriate superclass that can cover the characteristics of these products is abstracted, and then the specific subclass of this superclass determines which product to produce to achieve the purpose of polymorphism . The meaning of polymorphism is "one interface, multiple implementations", and the "interface" here is not only an abstract class modified by the Interface keyword, but should be an interface or abstract class in a broader sense, and the above code can actually be The purpose is achieved by designing Car as an abstract class through extends.

In a broader sense, the "factory pattern" actually includes three design patterns from simple to complex: simple factory, factory method, and abstract factory.

One of the well-known OOD design principles is called the Liskov Substitution Principle (LSP) . Its essence is to talk about upward transformation. Its content is: Any place that accepts a supertype should be able to accept a subtype. In other words , if a base class is used, it must be applicable to its subclass, and the program cannot detect the base class object and the subclass. object distinction. LSP is the cornerstone of inheritance and reuse. Only when the derived class can replace the base class and the functions of the software are not affected, the base class can be truly reused. 



Guess you like

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