Writing in the front

  • Take notes on learning design patterns
  • Improve the flexible use of design patterns

Learning to address

www.bilibili.com/video/BV1G4…

www.bilibili.com/video/BV1Np…

Refer to the article

C.biancheng.net/view/1317.h…

Program source codeGitee.com/zhuang-kang…

7. Factory mode

7.1 Definition and characteristics of factory mode

Definition of factory pattern: Define a factory interface to create product objects, deferring the actual creation of product objects to concrete subfactory classes. This satisfies the “create and use separation” characteristic required in the creative pattern.

According to the actual business scenarios, there are three different implementation modes of factory mode, namely simple factory mode, factory method mode and abstract factory mode.

We call the objects being created “products” and the objects creating the products “factories.” If you want to create a small number of products, you can do it with a single factory class, which is called the “simple Factory pattern.”

The Method for creating instances in a Simple Factory Pattern is usually static, so the Simple Factory Pattern is also called static Factory Method Pattern.

In simple terms, the simple Factory pattern has a concrete factory class that can generate multiple different products and is a creative design pattern. The simple factory pattern is not one of GoF’s 23 design patterns.

The simple factory pattern adds a concrete product class and a corresponding concrete factory class for every product, which increases the complexity of the system and violates the “open and closed principle”.

Advantages:

  1. The factory class contains the logical judgment necessary to determine which instance of a product to create and when. The client can be relieved of the responsibility of creating product objects directly, making it easy to create corresponding products. The responsibilities of plant and product are clearly differentiated.
  2. The client does not need to know the class name of the specific product being created, just the parameters.
  3. Configuration files can also be introduced to replace and add new concrete product classes without modifying the client code.

Disadvantages:

  1. The simple factory mode has a single factory class, which is responsible for the creation of all products. The responsibility is too heavy. Once an exception occurs, the whole system will be affected. And the factory class code will be very bloated, against the principle of high aggregation.
  2. Using the simple factory pattern increases the number of classes in the system (introducing new factory classes), increasing the complexity and difficulty of understanding the system
  3. It is difficult to expand the system. Once a new product is added, the factory logic has to be modified. The logic may be too complicated when there are many product types
  4. The simple factory pattern uses the static factory approach, which prevents the factory roles from forming an inheritance-based hierarchy.

7.2 Structure and implementation of factory mode

The main roles of the simple Factory pattern are as follows:

  • SimpleFactory: is the core of the SimpleFactory pattern and is responsible for implementing the internal logic that creates all instances. The method of creating a product class for a factory class can be called directly from the outside world to create the desired product object.
  • Abstract Product: Is the parent of all objects created by a simple factory and is responsible for describing the common interface shared by all instances.
  • Concrete Products: Are the creation targets of the simple factory pattern.

Shape

package com.zhuang.factory.simplefactory;

/ * * *@Classname Shape
 * @DescriptionProduct interface class *@Date2021/3/18 double-break *@Created by dell
 */

public interface Shape {
    void draw(a);
}
Copy the code

Circle

package com.zhuang.factory.simplefactory;

/ * * *@Classname Circle
 * @DescriptionProduct implementation classes *@Date 2021/3/18 15:43
 * @Created by dell
 */

public class Circle implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

Rectangle

package com.zhuang.factory.simplefactory;

/ * * *@Classname Rectangle
 * @DescriptionProduct implementation classes *@Date2021/3/18 double-break *@Created by dell
 */

public class Rectangle implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

Square

package com.zhuang.factory.simplefactory;

/ * * *@Classname Square
 * @DescriptionProduct implementation classes *@Date2021/3/18 double-break *@Created by dell
 */

public class Square implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

ShapeFactory

package com.zhuang.factory.simplefactory;

/ * * *@Classname ShapeFactory
 * @DescriptionSimple factory class *@Date 2021/3/18 15:43
 * @Created by dell
 */

public class ShapeFactory {
    public static Shape createShape(String shapeType) {
        if ("Rectangle".equalsIgnoreCase(shapeType)) {
            return new Rectangle();
        }
        if ("Circle".equalsIgnoreCase(shapeType)) {
            return new Circle();
        }
        if ("Square".equalsIgnoreCase(shapeType)) {
            return new Square();
        }
        return null; }}Copy the code

ShapeFactoryTest

package com.zhuang.factory.simplefactory;

/ * * *@Classname ShapeFactoryTest
 * @DescriptionSimple factory test classes *@Date 2021/3/18 15:47
 * @Created by dell
 */

public class ShapeFactoryTest {
    public static void main(String[] args) {
        Shape rectangle = ShapeFactory.createShape("Rectangle");
        rectangle.draw();

        Shape circle = ShapeFactory.createShape("Circle");
        circle.draw();

        Shape square = ShapeFactory.createShape("Square"); square.draw(); }}Copy the code

The java.util. Calendar source code uses the simple factory pattern

7.3 Definition and characteristics of abstract factory pattern

The Abstract Factory pattern creates other factories around a gigafactory. The gigafactory is also known as the factory of other factories. This type of design pattern is the creation pattern, which provides the best way to create objects. In the abstract factory pattern, the interface is responsible for creating a factory of related objects. Without explicitly specifying their classes, each generated factory can provide objects according to the factory pattern.

To use the abstract factory pattern, the following conditions are generally met.

  • There are multiple product families in the system, and each specific factory creates the same family of products that belong to a different hierarchical structure.
  • The system can only consume one family of products at a time, that is, products of the same family.

The main advantages are as follows:

  • Multiple levels of associated products within a product family can be managed together within a class, rather than having to introduce multiple new classes.
  • When a product family is required, an abstract factory ensures that the client always uses only the product group of the same product.
  • Abstract factories enhance the extensibility of programs, and when a new product family is added, there is no need to modify the original code, meeting the open closed principle.

Its disadvantages are:

  • All factory classes need to be modified when a new product needs to be added to the product family. The system is abstract and difficult to understand.

7.4 Structure and implementation of abstract factory pattern

7.4.1 Abstract factory pattern structure

  1. Abstract Factory: Provides an interface for creating products. It contains multiple product-creating methods, newProduct(), that can create multiple levels of products.
  2. Concrete Factory: It mainly realizes several abstract methods in the abstract Factory to complete the creation of Concrete products.
  3. Abstract Products: Defines a specification for a Product and describes its main features and functions. The Abstract factory pattern has multiple abstract products.
  4. Concreteproducts: Interfaces that implement abstract product roles and are created by concrete factories in a many-to-one relationship.

7.3.2 Code implementation

Shape

package com.zhuang.factory.absfactory;

/ * * *@Classname Shape
 * @DescriptionProduct interface class *@Date2021/3/18 double-break *@Created by dell
 */

public interface Shape {
    void draw(a);
}
Copy the code

Circle

package com.zhuang.factory.absfactory;

/ * * *@Classname Circle
 * @DescriptionProduct implementation classes *@Date 2021/3/18 15:43
 * @Created by dell
 */

public class Circle implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

Square

package com.zhuang.factory.absfactory;

/ * * *@Classname Square
 * @DescriptionProduct implementation classes *@Date2021/3/18 double-break *@Created by dell
 */

public class Square implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

Rectangle

package com.zhuang.factory.absfactory;


/ * * *@Classname Rectangle
 * @DescriptionProduct implementation classes *@Date2021/3/18 double-break *@Created by dell
 */

public class Rectangle implements Shape {
    @Override
    public void draw(a) {
        System.out.println(Rectangle--> Rectangle--> Rectangle); }}Copy the code

ShapeFactory

package com.zhuang.factory.absfactory;

/ * * *@Classname ShapeFactory
 * @DescriptionSimple factory class *@Date 2021/3/18 15:43
 * @Created by dell
 */

public class ShapeFactory extends AbstractFactory {
    @Override
    public Shape createShape(String shapeType) {
        if ("Rectangle".equalsIgnoreCase(shapeType)) {
            return new Rectangle();
        }
        if ("Circle".equalsIgnoreCase(shapeType)) {
            return new Circle();
        }
        if ("Square".equalsIgnoreCase(shapeType)) {
            return new Square();
        }
        return null;
    }

    @Override
    public Color createColor(String colorType) {
        return null; }}Copy the code

Color

package com.zhuang.factory.absfactory;

/ * * *@Classname Color
 * @DescriptionColor product interface class *@Date 2021/3/18 16:03
 * @Created by dell
 */

public interface Color {
    void fill(a);
}
Copy the code

Red

package com.zhuang.factory.absfactory;

/ * * *@Classname Red
 * @DescriptionColor product implementation class *@Date 2021/3/18 16:03
 * @Created by dell
 */

public class Red implements Color {
    @Override
    public void fill(a) {
        System.out.println("Red--> Fill with Red"); }}Copy the code

Yellow

package com.zhuang.factory.absfactory;

/ * * *@Classname Yellow
 * @DescriptionColor product implementation class *@Date 2021/3/18 16:04
 * @Created by dell
 */

public class Yellow implements Color {
    @Override
    public void fill(a) {
        System.out.println("Red--> Fill yellow"); }}Copy the code

Black

package com.zhuang.factory.absfactory;

/ * * *@Classname Black
 * @DescriptionColor product implementation class *@Date 2021/3/18 16:05
 * @Created by dell
 */

public class Black implements Color {
    @Override
    public void fill(a) {
        System.out.println("Red--> Fill black"); }}Copy the code

ColorFactory

package com.zhuang.factory.absfactory;

import com.zhuang.factory.simplefactory.Circle;
import com.zhuang.factory.simplefactory.Rectangle;
import com.zhuang.factory.simplefactory.Square;

/ * * *@Classname ColorFactory
 * @DescriptionColor factory class writing *@Date 2021/3/18 16:05
 * @Created by dell
 */

public class ColorFactory extends AbstractFactory {
    @Override
    public Shape createShape(String shapeType) {
        return null;
    }

    @Override
    public Color createColor(String colorType) {
        if ("Red".equalsIgnoreCase(colorType)) {
            return new Red();
        }
        if ("Black".equalsIgnoreCase(colorType)) {
            return new Black();
        }
        if ("Yellow".equalsIgnoreCase(colorType)) {
            return new Yellow();
        }
        return null; }}Copy the code

AbstractFactory

package com.zhuang.factory.absfactory;

/ * * *@Classname AbstractFactory
 * @DescriptionProduct family abstract classes *@Date 2021/3/18 16:06
 * @Created by dell
 */

public abstract class AbstractFactory {
    public abstract Shape createShape(String shapeType);

    public abstract Color createColor(String colorType);
}
Copy the code

AbstractFactoryProducer

package com.zhuang.factory.absfactory;

/ * * *@Classname AbstractFactoryProducer
 * @DescriptionFactory class * for the abstract class@Date2021/3/18 "*@Created by dell
 */

public class AbstractFactoryProducer {
    public static AbstractFactory createFactory(String choice) {
        if ("Shape".equalsIgnoreCase(choice)) {
            return new ShapeFactory();
        }
        if ("Color".equalsIgnoreCase(choice)) {
            return new ColorFactory();
        }
        return null; }}Copy the code

AbstractFactoryProducerTest

package com.zhuang.factory.absfactory;

/ * * *@Classname AbstractFactoryProcucerTest
 * @DescriptionAbstract class factory class test class *@Date 2021/3/18 16:15
 * @Created by dell
 */

public class AbstractFactoryProducerTest {
    public static void main(String[] args) {
        AbstractFactory shapeFactory = AbstractFactoryProducer.createFactory("Shape");
        assertshapeFactory ! =null;
        Shape rectangle = shapeFactory.createShape("Rectangle");
        Shape circle = shapeFactory.createShape("Circle");
        Shape square = shapeFactory.createShape("Square");
        rectangle.draw();
        circle.draw();
        square.draw();
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
        AbstractFactory colorFactory = AbstractFactoryProducer.createFactory("Color");
        Color red = colorFactory.createColor("Red");
        Color yellow = colorFactory.createColor("Yellow");
        Color black = colorFactory.createColor("Black"); red.fill(); yellow.fill(); black.fill(); }}Copy the code

7.5 Application scenarios of the Abstract Factory Mode

  1. When the objects to be created are a series of interrelated or interdependent product families, such as TV sets, washing machines, air conditioners, etc.
  2. There are multiple product families in the system, but only one of them is used at a time. For example, someone only likes to wear a certain brand of clothes and shoes.
  3. The system provides the product class library, and all products have the same interface, the client does not depend on the creation details and internal structure of the product instance.

Write in the last

  • If my article is useful to you, please give me a click 👍, thank you 😊!
  • If you have any questions, please point them out in the comments section! 💪