Java Design Patterns -- Factory Patterns

Posted by cgraz on Fri, 17 May 2019 02:15:08 +0200

Factory pattern: It is mainly used to instantiate classes with common interfaces. Factory pattern can dynamically determine which class should be instantiated.

The Form of Factory Model
There are several main types of factory models:
1: Simple Factory: not conducive to the production of a series of products.
2: Factory Method: Also known as Polymorphic Factory
3: Abstract Factory: Also known as toolbox, produces product family, but it is not conducive to generating new products.

One: Simple Factory Model

Simple factory mode is also called static factory method mode. Renaming shows that this pattern must be very simple. It exists for a simple purpose: to define an interface for creating objects.  
In the simple factory model, a factory class is at the center of the call to instantiate the product class. It decides which product class should be instantiated, just as a traffic policeman stands in the traffic flow and decides which direction to let the vehicle flow in.  
Let's first look at its composition:

     1) Factory role: This is the core of this model, which contains certain business logic and judgment logic. In java, it is often implemented by a specific class.

     2) abstract product roles: It is generally the parent class inherited by a specific product or the interface implemented. In java, it is implemented by interfaces or abstract classes.

     3) Specific product roles: The object created by the factory class is an example of this role. It is implemented by a specific class in java.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Simple factory mode simple implementation:

Here we use the production of computers as an example. Suppose there is an OEM manufacturer who can now produce Lenovo computers. With the expansion of the business, the OEM manufacturer will also produce HP and ASUS computers, so we need to use a separate class to specialize in the production of computers, which uses a simple factory model. Here we implement the simple factory model:

Creating abstract product classes

Let's create an abstract product class for a computer, which has an abstract method for starting a computer:

public abstract class Computer {
    /**
     * The abstract method of product is realized by specific product class.
     */
    public abstract void start();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Create specific product classes

Then we created all brands of computers. They all inherited their parent Computer and implemented the parent start method.
Lenovo computer:

public class LenovoComputer extends Computer{
    @Override
    public void start() {
        System.out.println("Lenovo Computer Start");
    }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

HP Computer:

public class HpComputer extends Computer{
    @Override
    public void start() {
        System.out.println("Hewlett-Packard Computer Start-up");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Asus Computer:

public class AsusComputer extends Computer {
    @Override
    public void start() {
        System.out.println("Asus Computer Start-up");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Create factory classes
Next, create a factory class that provides a static method, createComputer, to produce computers. You just need to import the brand of the computer you want to produce, and it will instantiate the computer object of the corresponding brand:

public class ComputerFactory {
    public static Computer createComputer(String type){
        Computer mComputer=null;
        switch (type) {
            case "lenovo":
                mComputer=new LenovoComputer();
               break;
            case "hp":
                mComputer=new HpComputer();
                break;
            case "asus":
                mComputer=new AsusComputer();
                break;

        }
        return mComputer;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Client calls factory class

The client calls the factory class, passes in "hp" to produce HP computer and calls the start method of the computer object:

public class CreatComputer {
    public static void main(String[]args){
      ComputerFactory.createComputer("hp").start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5

II. Factory Method Model

Definition of Factory Method Patterns

Define an interface for creating objects so that subclasses decide which class to instantiate. Factory methods delay the instantiation of a class to its subclasses.

The following example:
Creating Abstract products is the same as creating concrete products.

Create Abstract factories: There's a createComputer method that produces whatever brand of computer you want to produce.

public abstract class ComputerFactory {
    public abstract <T extends Computer> T createComputer(Class<T> clz);
}
  • 1
  • 2
  • 3

Specific factory

Quanta Dai Factory is a concrete factory. He inherits the abstract factory and produces computers from different manufacturers through reflection.

/**
 * Quanta Generation Factory
 */
public class GDComputerFactor extends ComputerFactory {
    @Override
    public <T extends Computer> T createComputer(Class<T> clz) {
        Computer computer=null;
        String classname=clz.getName();

        try {
            //Making computers from different manufacturers by reflection
            computer= (Computer) Class.forName(classname).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) computer;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Client call:

public class Client {
    public static void main(String[]args) {
        ComputerFactory computerFactory = new GDComputerFactor();
        LenovoComputer mLenovoComputer=computerFactory.createComputer(LenovoComputer.class);
        mLenovoComputer.start();
        HpComputer mHpComputer=computerFactory.createComputer(HpComputer.class);
        mHpComputer.start();
        AsusComputer mAsusComputerr=computerFactory.createComputer(AsusComputer.class);
        mAsusComputerr.start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Factory Method and Simple Factory

As we all know, the simple factory model contains the necessary logical judgment, dynamically instantiates the related classes according to different conditions, removes the dependence on specific products for the client, and at the same time brings a problem: if we want to increase the products, such as we want to produce Apple computers, then we need to add a C in the factory class. ASE branch condition, which violates the principle of open and closed, we are also open to modification, students who do not understand the principle of open and closed can view the design pattern (1) six principles of design this article. The factory method model does not violate this open and closed principle, if we need to produce Apple computers, do not need to modify the factory class, just create products.

3. Abstract Factory Model

Definition of abstract factory pattern
Provide an interface for creating a set of related or interdependent objects without specifying their specific classes.

Simple implementation of abstract factory pattern

Lenovo and Hewlett-Packard's computers are divided into two product lines: a desktop and a laptop. In order to solve the problem of adding product lines, we use abstract factory pattern to implement.

Abstract products
First, we define abstract product classes:

public abstract class DesktopComputer {
  public abstract void start();
}
public abstract class NotebookComputer {
   public abstract void start();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

The two abstract product classes are DesktopComputer and Notebook Computer, which define two product lines: desktop and notebook. They all define the start method, which is used to start the computer.  
Specific products
Specific products are Lenovo and HP's desktop and laptop, as shown below.

public class LenovoDesktopComputer extends DesktopComputer {
    @Override
    public void start() {
        System.out.println("Lenovo desktop computer startup");
    }
}

public class HpDesktopComputer extends DesktopComputer {
    @Override
    public void start() {
        System.out.println("HP desktop computer boot");
    }
}

public class LenovoNotebookComputer extends NotebookComputer {
    @Override
    public void start() {
        System.out.println("Lenovo laptop boot");
    }
}
public class HpNotebookComputer extends NotebookComputer {
    @Override
    public void start() {
        System.out.println("Hewlett-Packard Laptop Boot");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Abstract factory
Then create an abstract factory that produces computers, as shown below.

public abstract class ComputerFactory {
    public abstract DesktopComputer createDesktopComputer();
    public abstract NotebookComputer createNotebookComputer();
}
  • 1
  • 2
  • 3
  • 4

Two methods are defined for the production of desktop computers and laptops, respectively.

Specific factories
Define Lenovo and HP Factory:

public class LenovoFactory extends ComputerFactory {
    @Override
    public DesktopComputer createDesktopComputer() {
        return new LenovoDesktopComputer();
    }
    @Override
    public NotebookComputer createNotebookComputer() {
        return new LenovoNotebookComputer();
    }
}

public class HpFactory extends ComputerFactory {
    @Override
    public DesktopComputer createDesktopComputer() {
        return new HpDesktopComputer();
    }

    @Override
    public NotebookComputer createNotebookComputer() {
        return new HpNotebookComputer();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Lenovo and Hewlett-Packard factories are used to produce desktop and notebook computers in two different product lines.

Client call
Finally, the client is written:

public class Client {
    public static void main(String[]args) {
        ComputerFactory lenocoFactory=new LenovoFactory();
        lenocoFactory.createDesktopComputer().start();
        lenocoFactory.createNotebookComputer().start();
        ComputerFactory hpFactory=new HpFactory();
        hpFactory.createDesktopComputer().start();
        hpFactory.createNotebookComputer().start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

The desktop and laptop computers are manufactured with Lenovo Factory and HpFactory respectively, and they are started by calling the start method.

Use scenarios for abstract factory patterns

A system does not depend on the details of how product line instances are created, assembled, and expressed.
There are more than one product line in the system, and only one product line is used at a time.
A product line (or a set of unrelated objects) has the same constraints.

Topics: Java