Study notes on factory mode of 23 design modes

What is the factory model?

As the name suggests, factory is to create products. According to whether the products are specific products or specific factories, it can be divided into simple factory mode and factory method mode. According to the degree of abstraction of factories, it can be divided into factory method mode and abstract factory mode. This mode is used to encapsulate and manage the creation of objects. It is a creation mode. This paper analyzes the application scenarios and advantages and disadvantages of the three factory modes step by step from a specific example.

1. Simple factory mode

What is the simple factory model?

Simple factory is also called static factory. Before the program is compiled into bytecode file, the encapsulation relationship of factory class to some objects has been established. You only need to obtain the factory object according to the parameters to obtain the corresponding target object.

advantage:

  • When creating an object, the client only needs to remember specific parameters, not complex class names and implementation process. (packaging and partial decoupling are realized)
  • To create an object, you do not need to instantiate it separately, but directly obtain the example through the factory class (realize reuse)

Disadvantages:

  • The logic of instantiated objects is encapsulated in a factory class, and the factory class must be modified separately every time the requirements change (in violation of the opening and closing principle).
  • Inconvenient to extend subclasses

Application scenario:

It is suitable for the situation that there are few products with simple business and will not be modified once they are created

Simple plant logic structure diagram:


AbstractProduct: abstract factory is to extract all common methods of Product into an abstract class.
Product: it is a specific product category. Take mobile phones as an example, then product a is like apple mobile phone and product B is like Xiaomi mobile phone.
Factory: refers to the OEM object and factory class corresponding to the Product. According to the above example object, at this time, factory is like Foxconn factory, which processes mobile phones of various brands. You can select and process mobile phones of different brands through selection.

Specific implementation:
Interface Phone
👇

public interface Phone {
    void makePhone();
}

Implementation class: IPone
👇

public class IPhone implements Phone{
    @Override
    public void makePhone() {
        System.out.println("Production of Apple phones");
    }
}

Concrete implementation class MiPhone
👇

public class MiPhone implements Phone{
    @Override
    public void makePhone() {
        System.out.println("Production of Xiaomi mobile phone");
    }
}

Factory class PhoneFactory
👇

public class PhoneFactory {
    public Phone getPhone(String type){
        if ("IPhone".equals(type)){
            return new IPhone();
        }
        if ("MiPhone".equals(type)){
            return new MiPhone();
        }
        return null;
    }
}

Class startup
👇

public class Test {
    public static void main(String[] args) {
        PhoneFactory phoneFactory = new PhoneFactory();
        Phone iPhone = phoneFactory.getPhone("IPhone");
        Phone miPhone = phoneFactory.getPhone("MiPhone");
        iPhone.makePhone();
        miPhone.makePhone();
    }
}

Specific results
👇

2. Factory method model

What is the factory method model?

In real life, the social division of labor is becoming more and more detailed and specialized. All kinds of products are produced in special factories, rather than including the production business of other mobile phone manufacturers like Foxconn, but each brand has its own production factory. Factory method mode is a further abstraction of simple factory mode. Its advantage is that the system can introduce new products without modifying the original code, that is to meet the opening and closing principle.

advantage:

  • Users only need to know the name of the specific factory to get the desired product, without knowing the specific creation process of the product.
  • Flexibility is enhanced. For the creation of new products, you only need to write one more corresponding factory class.
  • Typical decoupling framework. The high-level module only needs to know the abstract class of the product, does not need to care about other implementation classes, and meets the Demeter rule, the dependency inversion principle and the Richter substitution principle.

Disadvantages:

  • The number of classes is easy to be too many, which increases the complexity and the abstraction and understanding difficulty of the system.
  • Abstract products can only produce one product.

Usage scenario:

  • The customer only knows the name of the factory that created the product, but does not know the specific product name
  • The task of creating objects is completed by one of multiple concrete sub factories, while the abstract factory only provides the interface to create products.
  • Customers don't care about the details of creating products, they only care about the brand of products.

Logic structure diagram of plant method:

AbstractProduct: abstract product, which extracts the common methods of this kind of products.
Product1: specific product categories. Specific product production details are implemented internally, such as IPhone.
Product2: specific product categories. Specific product production details are implemented internally, such as MiPhone.
AbstractFactory: abstract factory, which extracts the method for all factories to create the same kind of products.
ConcreteFactory1: specific factory types. A factory can only produce one type of products. For example, IPhoneFactory can only produce iPhones and MiPhoneFactory can only produce miphones. What if we need to produce other products? At this time, you only need to add a specific product category and the corresponding factory.
ConcreteFactory2: as above.

Specific implementation:

//Abstract product
public interface Phone {
    void makePhone();
}
//Specific products: IPhone
class IPhone implements Phone{
    @Override
    public void makePhone() {
        System.out.println("Production of Apple phones");
    }
}
//Specific product MiPhone
class MiPhone implements Phone {
    @Override
    public void makePhone() {
        System.out.println("Production of Xiaomi mobile phone");
    }
}
//Abstract factory has the method of producing products
interface AbstractFactory {
    public Phone createPhone();
}
//Specific Apple factory
class IPhoneFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
}
//Specific Xiaomi factory
class MiPhoneFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new MiPhone();
    }
}

public class Test_gongchang {
    public static void main(String[] args) {
        IPhoneFactory iPhoneFactory = new IPhoneFactory();
        Phone phone = iPhoneFactory.createPhone();
        phone.makePhone();

        MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
        Phone phone1 = miPhoneFactory.createPhone();
        phone1.makePhone();
    }
}

The results are as follows:
👇

3. Abstract factory pattern

What is the abstract factory pattern?

No matter how the factory splits and abstracts the above two modes, they are only for one kind of product Phone. The factory method mode introduces the factory hierarchical structure to solve the problem of excessive responsibilities of factory classes in the simple factory mode. However, since each factory in the factory method mode only creates one class of specific objects, it will lead to too many factory classes in the system, which is bound to increase the overhead of the system. At this time, we can consider forming some relevant concrete classes into a "concrete class family", which is uniformly produced by the same factory. This is the basic idea of "abstract factory pattern" in this paper.

advantage:

  • It is convenient to add a new product grade without modifying the existing system, which conforms to the "opening and closing principle".
  • Separate specific classes. The customer manipulates the instance through the abstract interface, and the class names of the products are also separated in the implementation of the specific factory. They do not appear in the customer code.

Disadvantages:

  • Adding a new product family structure is troublesome, and the original system needs to be greatly modified, or even the abstract layer code needs to be modified, which will obviously bring great inconvenience and violate the "opening and closing principle". Because the abstract factory interface determines the set of products that can be created, it is difficult to extend the abstract factory to produce new kinds of products.

Application scenario:

  • Creating a series of related product objects (belonging to the same product family) together requires a lot of duplicate code
  • Provide a library of product classes. All products appear with the same interface, so that the client does not depend on the specific implementation.

Attention: friends here may not understand the concept of product family and product grade.
Notice it's coming!!!
Product grade: Product grade refers to the inheritance structure of products. For example, an abstract class of TV sets. Its subclasses are Haier TV sets, Hisense TV sets and Changhong TV sets. Abstract TV sets and TV sets of specific brands form a product grade.
Product family: in the abstract factory model, product family refers to a group of products produced by the same factory but located in different product levels. For example, Haier TV sets and refrigerators produced by Haier Electric Appliance Factory. Haier TV sets are located in the hierarchical structure of TV products, and Haier refrigerators are located in the hierarchical structure of refrigerator products. Haier TV sets and Haier refrigerators form a product family.
For details, please refer to: https://blog.csdn.net/w405722907/article/details/87798453

Abstract factory pattern logic structure


AbstractPhone: abstract class of mobile phone, which extracts public methods of mobile phone.
AbstractPC: an abstract class on the PC side of the computer, which extracts the public method of the mobile phone.
MiPhone and IPhone: specific mobile phone implementation classes, belonging to different product families.
MiPC and MAC: specific computer implementation classes belong to different product families, but MiPC and MiPhone belong to the same product group and different product levels. Mac and IPone belong to the same product group and different product levels.
AbstractFactory: abstract factory, which extracts the public methods of creating specific products at the factory.
MiFactory and AppleFactory: specific factory implementation classes. A brand factory is a product family.

Concrete implementation

👇

//Abstract products
interface Phone {
    void makePhone();
}
//Computer interface
interface Computer {
    void makeComputer();
}
//Specific product categories
class IPhone implements Phone {
    public IPhone() {
        this.makePhone();
    }
    @Override
    public void makePhone() {
        System.out.println("Apple factory produces Apple phones");
    }
}
//Specific product categories
class Mac implements Computer {
    public Mac() {
        this.makeComputer();
    }
    @Override
    public void makeComputer() {
        System.out.println("Apple factory production MAC");
    }
}
//The specific product category and the above products belong to different families
class MiComputer implements Computer {
    public MiComputer() {
        this.makeComputer();
    }
    @Override
    public void makeComputer() {
        System.out.println("Xiaomi factory produces notebook computers");
    }
}
//The specific product category and MiComputer belong to the same product family
class MiPhone implements Phone {
    public MiPhone() {
        this.makePhone();
    }
    @Override
    public void makePhone() {
        System.out.println("Xiaomi factory produces Xiaomi mobile phones");
    }
}
//Abstract the factory and extract the commonness of different product families
interface AbstractFactory {
    Phone createPhone();
    Computer createComputer();
}
//For a specific brand factory, all exhibits of a brand are a product family
class AppleFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
    @Override
    public Computer createComputer() {
        return new Mac();
    }
}
//Specific brand factory
class MiFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new MiPhone();
    }
    @Override
    public Computer createComputer() {
        return new MiComputer();
    }
}

public class Testttt {
    public static void main(String[] args) {
        AppleFactory appleFactory = new AppleFactory();
        appleFactory.createComputer();
        appleFactory.createPhone();

        MiFactory miFactory = new MiFactory();
        miFactory.createComputer();
        miFactory.createPhone();
    }
}

Operation results
👇

Keywords: Java Design Pattern

Added by metuin on Tue, 01 Mar 2022 09:16:14 +0200