Let you quickly understand the factory pattern

Tip: After the article is written, the table of contents can be automatically generated. For how to generate it, please refer to the help document on the right

foreword

`
The factory pattern is divided into simple factory (not included in the 23 design patterns), factory method, and abstract method; here I will summarize and explain the difference between the three in the simplest way, if you want to quickly understand the three Please read on for the specific usage, advantages and disadvantages of the mode!

A simple factory

definition

Three roles: factory class, abstract product class, concrete product class
Simple factory implementation principle:
1) Define a factory. The client only needs to pass the corresponding parameters to get the object from the factory, and does not need to care about how the specific product of the object is created;
2) The factory class is responsible for creating objects based on parameters

code example

Simple factory class as follows:

publicclass PhoneFactory {
    public static Phone createPhone(String type) {
        Phone phone = null;
        if ("huawei".equals(type)) {
            phone = new Huawei();
        } elseif ("xiaomi".equals(type)) {
            phone = new Xiaomi();
        } elseif ("apple".equals(type)) {
            phone = new IPhone();
        } else {
            System.out.println("Not currently supported");
        }
        return phone;
    }
}

Advantages and disadvantages

advantage:
1) Loosely coupled, the user does not need to know the specific implementation class, and only needs to pass in the specific parameters to get the desired object.
shortcoming:
1) It does not conform to the principle of opening and closing. When a new product is added, the factory class needs to be modified.
2) When there are many specific implementation products, if...else will be more, resulting in unsightly code

Factory methods can solve both problems

Second, the factory method

definition

Roles: Factory Base Class, Concrete Product Factory, Abstract Product, Concrete Product
Similar to Simple Factory 1, except that the factory form is changed to a combination of factory base class + specific product factory; the factory is no longer responsible for creating objects. Instead, use the Dependency Inversion Principle to get the concrete object to call.

code example

Factory base class

publicinterface PhoneFactory {
   Phone createPhone();
}

specific factory

publicclass HuaweiFactory implements PhoneFactory {
   @Override
   public Phone createPhone() {
      returnnew Huawei();
   }
}

client

 public static void main(String[] args) {
        PhoneFactory phoneFactory = new XiaomiFactory();
        Phone phone = phoneFactory.createPhone();
        phone.play()
    }

Advantages and disadvantages

advantage:
1) There is no need to judge and obtain the corresponding product through parameters
2) Reduced if...else problems in simple factories
3) It conforms to the principle of opening and closing, and achieves complete decoupling of product and factory codes; when adding new products, there is no need to modify the factory method, but only need to add a new product factory.

Disadvantage: When adding new products, it is necessary to add new products and product factories at the same time, which increases in pairs, which leads to the complexity of the system.

3. Abstract Factory

definition

On the basis of the factory pattern, it has been extended upwards. It puts together products with certain commonality, and the factory class provides common calling methods for these products, and then the caller calls the corresponding factory class according to their own needs. Get a product instance.

Class Diagram:

In order to better understand the abstract factory pattern, here I put a class diagram about colors and shapes:

The following explanation is helpful to understand this class diagram:
1) The seemingly unreasonable business in shape and color is produced by a factory
2) Shape: In addition to being a shape, a square and a circle have their own implementation methods.
3) Color: In addition to being colors, red, blue, and green also have their own implementation methods.

Specific implementation ideas (agent example)

1. Define two interfaces of shape and color, and specific shapes and colors implement their interfaces respectively.

shape

public interface Shape {
   void draw();
}

//square

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

//circle

public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

color

public interface Color {
   void fill();
}

//red

public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}

//blue

public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

2. Define an abstract factory, which has abstract shape and abstract color methods.

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape);
}

3. The shape factory class and the color factory class implement the abstract factory class to realize their own business logic.

shape abstract class

public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}

color abstract class

public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

4. Create a factory constructor (determine to obtain its product instance through parameters)

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

5) Client

 public static void main(String[] args) {
 
      //1, get the shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
      //Get an object of shape Circle
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      //Call the draw method of Circle
      shape1.draw();

     //2, get the color factory
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
      //Get object with color Red
      Color color1 = colorFactory.getColor("RED");
      //Call Red's fill method
      color1.fill();
     

 }

Advantages and disadvantages

Advantages: Gathering certain common products together can ensure that objects in a product family are always used.
Disadvantages: It reduces the scalability of the system. When adding new products, it needs to be added in the abstract class and also in the implementation class, which is more complicated.

If this blog is helpful to you, please remember to leave a comment + like it.

Tags: Java Design Pattern

Posted by brad.techguy on Mon, 05 Sep 2022 04:46:57 +0300