Factory mode:

When the creation logic is complex, consider using the factory pattern, which encapsulates the creation of objects and separates the creation and use of objects.

Factory mode, of create type

The actual code I put on Github: github.com/liangtengyu…

Application Scenarios:

Understanding the use of a design pattern can help us understand it more quickly. What are the benefits of creating objects using the factory pattern as opposed to new?

There are two main cases:

  • The first case is an example of rule configuration parsing, where there is if-else branching in the code to dynamically create different objects based on different types. In this case, we can consider using the factory pattern, pulling out the large block of if-else object creation code and putting it in the factory class.

  • In another case, although we don’t need to create different objects for different types, the creation of the individual objects themselves is more complex, and we can consider using the factory pattern.

Benefits: Because the factory pattern relies on an abstract architecture, it scales well by leaving the task of instantiating products to implementation classes. In other words, when the system needs to be more scalable, the factory model can be considered, different products are assembled with different implementation factories. In plain English, this means reducing the impact of code changes on product functionality.

Implementation method:

Simple Factory

First, let’s look at what the simple factory pattern is. Let’s explain this with an example.

Simple Factory model

public class Cocacola implements Cola {
    public String getCola(a) {
        return "Coca-Cola"; }}Copy the code
public class ColaFactory {

    public static Cola getInstance(Integer colaType) {
        if (1 == colaType) {
            return new Cocacola();
        } else if (2 == colaType) {
            return new Pepsicola();
        } else {
            return newFakecola(); }}}Copy the code
 public static void main(String[] args) {
        String drink = ColaFactory.getInstance(1).drink();
        System.out.println(drink);
    }
    // Coca-Cola
Copy the code

Although the code implementation of the simple factory pattern has multiple if branch judgment logic that violates the open and close principle, the extensibility and readability trade-offs of such code implementations are fine in most cases.

Factory Method

The factory method is a further extension of the simple factory, so said because the simple factory violates the open and close principle, and the factory method can solve this problem perfectly! Let’s see how it works!

Factory method – projects

For the application scenario of rule configuration file parsing, the Factory pattern requires the creation of many additional Factory classes, which also increases the code complexity. Moreover, each Factory class only does simple new operations, which is very thin (only one line of code), and there is no need to design a separate class. Therefore, In this application scenario, the simple factory pattern works better than the factory method pattern

public interface ColaFactory {// Factory interface
    Cola getCola(a);
}
Copy the code
public class CocaColaFactoryImpl implements ColaFactory {// Implement Coca-Cola factory
    public Cola getCola(a) {
        return  newCocacola(); }}Copy the code
public static void main(String[] args) {
    // When the factory method requires a coke, go directly to the corresponding factory to get it, rather than from the same factory according to the judgment of the simple factory
    // There is a factory for each cola
    ColaFactory pepsiColaFactory = new PepsiColaFactoryImpl();
    Cola cola = pepsiColaFactory.getCola();
    cola.getCola();
}
Copy the code

When should you use the factory method pattern rather than the simple factory pattern?

The reason why a code block is separated into a function or class is that the logic of the code block is too complex, which makes the code clearer, more readable and maintainable.

However, if the code block itself is not complex, just a few lines of code, there is no need to break it up into separate functions or classes. Based on this design idea, when the object creation logic is more complex, it is ok to not just a simple new, but to combine other class object, doing all sorts of initialization, we recommend using a factory method pattern, will create logical split into multiple complex factory class, let each factory class is not too complicated. With the simple factory pattern, putting all the creation logic into a single factory class leads to a complex factory class.

In addition, in some scenarios, if the object is not reusable, the factory class will return a different object each time. If we had used the simple factory pattern, we would have had to choose the first implementation that included if branching logic. If we also want to avoid annoying if-else branch logic, we recommend using the factory method pattern.

Abstract Factory

The abstract factory pattern is used in a special way and is not as common as the first two, so let’s look at it briefly

The simple factory only abstracts the coke product, the factory method abstracts the Coke factory, and the abstract factory abstracts the factory method again

Light can be tricky conceptually, but let’s do an example

Demand: now the product line has been adjusted. Although we produce cola with different brands, they are all transparent bottles, so we need to make our own characteristics. Different brands of Cola need to be painted with different colors.

Thinking: If at this time we will be coke production and color spraying are coupled in the factory method code, the subsequent adjustment will be very troublesome, also violates the open and closed principle, open for expansion, closed for modification, then we use abstract factory is more appropriate

public abstract class ColaAbstractFactory {Create an abstract factory class
    abstract ColaFactory getCola(String cola);
    abstract ColorFactory getColor(String color);
}
Copy the code
public class ColaAbstractFactoryImpl extends ColaAbstractFactory {

		// Implement abstract classes
   public ColaFactory getCola(String cola) {
        if ("cocacola".equals(cola)) {
            return new CocaColaFactoryImpl();
        } else if ("fake".equals(cola)) {
            return new FakeColaFactoryImpl();
        } else if ("pepsi".equals(cola)) {
            return new PepsiColaFactoryImpl();
        } else
            return null;
    }

    public ColorFactory getColor(String color) {
        if ("yellow".equals(color)) {
            return new YellowColorFactoryImpl();
        } else if ("blue".equals(color)) {
            return new BlueColorFactoryImpl();
        } else if ("red".equals(color)) {
            return new RedColorFactoryImpl();
        } else
            return null; }}Copy the code
public class RedColorFactoryImpl implements ColorFactory {// Paint on different color requirements. Other colors similar will not repeat the paste
    public String getColor(a) {
        System.out.println("Spray red bottle");
        return "Red bottle"; }}Copy the code

In the end, we want to get coke + red

public static String getColaAndColor(String cola,String color){
    ColaAbstractFactoryImpl colaAbstractFactory = new ColaAbstractFactoryImpl();

    ColaFactory cola = colaAbstractFactory.getCola(cola);
    ColorFactory red = colaAbstractFactory.getColor(color);

    Cola col = cola.getCola();
    String colo = red.getColor();
    return col.getCola()+"-"+colo;
}
Copy the code
public static void main(String[] args) {
    String colaAndColor = FactoryProducer.getColaAndColor("cocacola"."red");
    System.out.println(colaAndColor);

}
//output:Painted red to produce Coca-Cola Coca-Cola - red bottlesCopy the code

Concern public number: Java baodian