There are three main types of design patterns that are treated differently in design patterns: creation patterns, structural patterns, and behavior patterns.

Abstract Factory Pattern Builder Pattern Prototype Pattern Singleton Pattern

Before introducing the factory method pattern, you can look at the simple factory pattern

Simple Factory Pattern

The simple Factory pattern is one of the creation patterns, also known as Static Factory Method patterns, but is not one of the 23 GOF design patterns. The simple factory pattern is where a factory object determines which instances of a product class are created. The simple factory pattern is the simplest and most practical pattern in the family of factory patterns and can be understood as a special implementation of different factory patterns.

The essence of the simple factory pattern is that a factory class dynamically decides which instances of products that inherit from a parent class or interface should be created, based on the parameters passed in.

The roles and responsibilities contained in the pattern

The Factory role

The core of the simple factory pattern, which is responsible for implementing the internal logic to create all instances. The factory class’s method for creating a product class can be called directly from the outside to create the desired product object.

Abstract (Product) Product roles

The parent class of all objects created by the simple factory pattern, which is responsible for describing the common interface shared by all instances.

Concrete Product role

Is the creation target of a simple factory pattern, and all objects created are instances of a concrete class that acts as this role.

Example UML diagram

Here is the code

Abstract (Product) Product roles

/** * Pen interface */
public interface Pen {
    void write(a);
}
Copy the code

Concrete Product role

/** * ballpoint pen */
public class BallpointPen implements Pen {
    @Override
    public void write(a) {
        System.out.println("Writing: I am a ballpoint pen!"); }}Copy the code
/** * pencil */
public class Pencil implements Pen {
    @Override
    public void write(a) {
        System.out.println("Writing: I am a pencil!"); }}Copy the code
/** * Marker */
public class MarkerPen implements Pen {
    @Override
    public void write(a) {
        System.out.println("Writing: I am a marker!"); }}Copy the code

The Factory role

/** * create pen factory ** /
public class SimpleFactory {
    public static Pen getPen(String type) {
        switch(type){
            case "BallpointPen":return new BallpointPen();
            case "MarkerPen":return new MarkerPen();
            case "Pencil":return new Pencil();
            default:break;
        }
        return newPencil(); }}Copy the code

Another kind of Factory role

/** * create pen factory ** /
class SimpleFactoryTwo {
    private static final Map<String,Pen> PEN_MAP = new HashMap<>();
    static {
        PEN_MAP .put("BallpointPen".new BallpointPen());
        PEN_MAP .put("MarkerPen".new MarkerPen());
        PEN_MAP .put("Pencil".new Pencil());
    }
    public static Pen getPen(String type) {
        returnPEN_MAP .get(type); }}Copy the code

The test class

/ * * *@author yangqiang
 */
public class PenWithType {

    public static void main(String[] args) {
        Pen ballpointPen = SimpleFactory.getPen("BallpointPen");
        ballpointPen.write();
        Pen pencil = SimpleFactory.getPen("Pencil");
        pencil.write();
        Pen markerPen = SimpleFactory.getPen("MarkerPen"); markerPen.write(); }}Copy the code

As you can see from the above example, the concept of the simple factory pattern is that the client creates and retrieves objects through the factory class. Depending on the type passed in, the factory class is returned to the specific product the client needs. And then we’re going to consume

advantages
  • The factory class contains the necessary logical decisions. Different objects can be created depending on the type passed in by the client. Remove the responsibility of the client to create the object. The factory class creates the object. Client consumption object. Consistent with a single responsibility.
  • You can import a configuration file. Add specific products without changing the client
disadvantages
  • The responsibility for creating specific product objects is in the factory class, and if the factory class is abnormal, the entire system is 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 certain programs.
  • System expansion is difficult. Added new specific products when. You need to modify the code logic of the factory class. Inconsistent with the open closed principle. If there are too many specific products, the factory logic may be complicated, which is not conducive to the maintenance and expansion of the system
Applicable scenario
  • The factory class is responsible for creating a small number of objects. Does not complicate the entire code logic of the factory class
  • The client does not care about object creation at all. Only the type created for the specific product is known. The specific object class name is also unclear

FactoryMethod pattern

Before we expand on the concept of a factory method pattern, let’s take the above example of a simple factory pattern and remodel it. For the concrete class and the interface of the concrete class, we leave the original code unchanged

Abstract the Factory role

public interface Factory {
    Pen getPen(a);
}
Copy the code

The specific Factory role

/** * Ball pen factory */
public class BallpointPenFactory implements Factory {
    @Override
    public Pen getPen(a) {
        return newBallpointPen(); }}Copy the code
/** * Pencil Factory */
class PencilFactory implements Factory {
    @Override
    public Pen getPen(a) {
        return newPencil(); }}Copy the code

The client

/ * * *@author yangqiang
 */
public class PenFactoryMethod {
    public static void main(String[] args) {
        new BallpointPenFactory().getPen().write();
        newPencilFactory().getPen().write(); }}Copy the code

Our implementation of the above example is a factory method pattern is a simple implementation, by means of simple factory pattern transformation, we can find in the factory method pattern, we no longer provide a unified factory class to create all concrete class instance of the object, but with different specific class implements the different factory, The system provides a factory hierarchy with the same level as the concrete class.

The composition of the factory method pattern

  • The public interface (Pen) or superclass of the concrete type
  • Concrete implementation class (Pencil, BallpointPen)
  • Factory interface
  • Concrete factory (BallpointPenFactory, PencilFactory)

UML diagrams

The factory method pattern is a derivative of the simple factory pattern and solves many problems of the simple factory pattern. First, the full implementation of the ‘open – closed principle’, to achieve scalability. Second, a more complex hierarchy can be applied to situations where the product results are complex.

The factory method pattern is an extension of the simple factory pattern. It inherits the advantages of the simple factory pattern and makes up for the disadvantages of the simple factory pattern. The factory method pattern is one of the most frequently used design patterns and is the core pattern of many open source frameworks and API libraries.

advantages
  • In the factory method pattern, the factory method is used to create instances of concrete classes, while the details of concrete class instantiation are hidden from the customer. The user only needs to care about the factory corresponding to the concrete class, and does not need to care about the details of instance creation or even the class name of the concrete class, so as to realize the decoupling between the concrete class and the user.
  • The polymorphic design based on the factory interface and the common interface of specific types is the key to the factory method pattern. It allows the factory to determine what objects to create that implement the class, but the details of creating that object are encapsulated inside the factory. The factory method pattern is called the polymorphic factory pattern precisely because all concrete factory classes have a common interface or superclass.
  • Another advantage of using the factory method pattern is that when adding new concrete classes to the system, there is no need to modify the original code, only need to add the implementation of the new class and the corresponding factory of the new class, which fully conforms to the “open closed principle”.
disadvantages
  • When adding a new concrete implementation class, it is necessary to add the corresponding factory class, and the number of classes in the system will increase in pairs, which increases the complexity of the system to some extent. The more classes there are, the more classes need to be compiled, increasing the system overhead.
  • Considering the extensibility of the system, it is necessary to introduce an abstraction layer, which is used for definition in the client code, increasing the abstractness and understanding difficulty of the system, and DOM, reflection and other technologies may be used in the implementation, which increases the difficulty of system implementation.
Applicable scenario

The client does not need to know the class of the object it needs. In the factory method pattern, the client does not need to know the class name of the concrete class, only its factory, where instances of the concrete class are created.