Writing in the front

  • Take notes on learning design patterns
  • Improve flexibility in the use of design patterns

Learning to address

https://www.bilibili.com/video/BV1G4411c7N4

https://www.bilibili.com/video/BV1Np4y1z7BU

Refer to the article

http://c.biancheng.net/view/1317.html

Project source https://gitee.com/zhuang-kang/DesignPattern

7. Factory mode

7.1 Definition and characteristics of factory mode

Factory pattern definition: Define a factory interface to create a product object, deferring the actual creation of a product object to a concrete subfactory class. This satisfies the “separation of creation from use” characteristic required in the creation pattern.

According to the actual business scenarios, the factory pattern can be implemented in three different ways, namely, simple factory pattern, factory method pattern and abstract factory pattern.

We refer to the object being created as a “product” and the object creating the product as a “factory.” If there are not many products to create, a single factory class can do it. This pattern is called the “simple factory pattern.”

The Simple Factory Pattern is also known as the static Factory Method Pattern because the methods used to create instances in a Simple Factory Pattern are usually static methods.

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

The simple factory model adds a specific product class and a corresponding specific factory class for each additional product, which increases the complexity of the system and violates the “open closed principle”.

Advantages:

  1. The factory class contains the logical judgments necessary to determine when to create an instance of which product. The client can be exempted from the responsibility of directly creating the product object, and it is very convenient to create the corresponding product. There is a clear separation of factory and product responsibilities.
  2. The client does not need to know the class name of the specific product being created, just the parameters.
  3. You can also introduce configuration files to replace and add new specific product classes without modifying the client code.

Disadvantages:

  1. The simple factory model has a single type of factory, which is responsible for the creation of all products, and the responsibility is too heavy. Once abnormal, the whole system will be affected. And the factory code would be very bloated and violate 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 new products are added, factory logic has to be modified, which may cause too complicated logic when there are many product types
  4. The simple factory pattern uses the static factory method, which makes it impossible for factory roles to form hierarchies based on inheritance.

7.2 Structure and implementation of factory pattern

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 to create all instances. The factory class’s method for creating a product class can be called directly from the outside world to create the desired product object.
  • Abstract Product: is the parent class of all objects created by the simple factory and is responsible for describing the common interface shared by all instances.
  • ConcreteProduct: Is the creation target of the Simple Factory pattern.

Shape

package com.zhuang.factory.simplefactory; /** * @className Shape * @description * @date 2021/3/18 15:40 * @created by dell */ public interface Shape {void () draw(); }

Circle

package com.zhuang.factory.simplefactory; /** * @ClassName * @Description * @Date 2021/3/18 15:43 * @Created by Dell */ public class Circle Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

Rectangle

package com.zhuang.factory.simplefactory; /** * @ClassName Rectangle * @Description Rectangle * @Date 2021/3/18 15:40 * @Created by Dell */ public class Rectangle Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

Square

package com.zhuang.factory.simplefactory; /** * @ClassName Square * @Description * @Date 2021/3/18 15:40 * @Created by Dell */ public class Square Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

ShapeFactory

package com.zhuang.factory.simplefactory; /** * @ClassName ShapeFactory * @Description * @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; }}

ShapeFactoryTest

package com.zhuang.factory.simplefactory; /** * @ClassName ShapeFactoryTest * @Description * @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(); }}

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

7.3 Definition and characteristics of the abstract factory pattern

The Abstract Factory pattern is about creating other factories around a Gigafactory. The Gigafactory is also known as a factory for other factories. This type of design pattern is a creation pattern, and it provides one of the best ways to create objects. In the abstract factory pattern, interfaces are the factories responsible for creating a related object without explicitly specifying their classes, and each generated factory can provide objects according to the factory pattern.

The following conditions are generally required to use the abstract factory pattern.

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

The main advantages are as follows:

  • Multiple levels of related products within a product family can be managed together within a class, rather than having to introduce multiple new classes to manage them.
  • When a product family is needed, an abstract factory ensures that clients always use only product groups of the same product.
  • Abstract factory enhances the extensibility of the program, when a new product family is added, there is no need to modify the original code, to meet the open closed principle.

Its disadvantages are:

  • All factory classes need to be modified when a new product is added to the product family. It increases the abstractness and difficulty of understanding the system.

7.4 Structure and implementation of abstract factory pattern

7.4.1 Structure of the abstract factory pattern

  1. Abstract Factory: Provides an interface to create a product. It contains multiple product-creation methods, newProduct(), which can create multiple products of different levels.
  2. Concrete Factory: It mainly realizes multiple abstract methods in the abstract Factory to complete the creation of specific products.
  3. Abstract Product: Defines the specification of the Product and describes the main features and functions of the Product. The Abstract Factory pattern has multiple abstract products.
  4. ConcreteProduct: Implements the interface defined by the abstract product role, created by the concrete factory, and has a many-to-one relationship with the concrete factory.

7.3.2 Code implementation

Shape

package com.zhuang.factory.absfactory; /** * @className Shape * @description * @date 2021/3/18 15:40 * @created by dell */ public interface Shape {void () draw(); }

Circle

package com.zhuang.factory.absfactory; /** * @ClassName * @Description * @Date 2021/3/18 15:43 * @Created by Dell */ public class Circle Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

Square

package com.zhuang.factory.absfactory; /** * @ClassName Square * @Description * @Date 2021/3/18 15:40 * @Created by Dell */ public class Square Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

Rectangle

package com.zhuang.factory.absfactory; /** * @ClassName Rectangle * @Description Rectangle * @Date 2021/3/18 15:40 * @Created by Dell */ public class Rectangle Implements Shape {@Override public void draw() {System.out.println("Rectangle-- Rectangle "); }}

ShapeFactory

package com.zhuang.factory.absfactory; /** * @ClassName ShapeFactory * @Description * @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; }}

Color

package com.zhuang.factory.absfactory; /** * @className Color * @description Color * @date 2021/3/18 16:03 * @created by dell */ public interface Color { void fill(); }

Red

package com.zhuang.factory.absfactory; /** * @ClassName Red * @Description * @Date 2021/3/18 16:03 * @Created by Dell */ public class Red implements Color {@override public void fill() {System.out.println("Red--> fill Red "); }}

Yellow

package com.zhuang.factory.absfactory; /** * @className Yellow * @description * @date 2021/3/18 16:04 * @created by dell */ public class Yellow Implements Color {@Override public void fill() {System.out.println("Red--> "); }}

Black

package com.zhuang.factory.absfactory; /** * @ClassName Black * @Description * @Date 2021/3/18 16:05 * @Created by Dell */ public class Black Implements Color {@Override public void fill() {System.out.println("Red--> "); }}

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 * @Description * @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; }}

AbstractFactory

package com.zhuang.factory.absfactory; /** * @ClassName AbstractFactory * @Description * @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); }

AbstractFactoryProducer

package com.zhuang.factory.absfactory; /** * @ClassName abstractFactoryProducer * @Description * @Date 2021/3/18 16:10 * @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; }}

AbstractFactoryProducerTest

package com.zhuang.factory.absfactory; / * * * @ the Classname AbstractFactoryProcucerTest * @ the Description of abstract 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"); assert shapeFactory ! = 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(); }}

7.5 Application scenarios of the abstract factory pattern

  1. When the objects to be created are a series of interrelated or interdependent product families, such as television sets, washing machines, air conditioners in an electrical factory, etc.
  2. There are multiple product families in the system, but only one family of products is used at a time. For example, some people only like to wear a certain brand of clothes and shoes.
  3. The product class library is provided in the system, and the interface of all products is the same, and the client does not depend on the creation details and internal structure of product instances.

Write in the last

  • If my article is useful to you, please click 👍, thank you!
  • Let me know in the comments section if you have any questions! 💪