Factory pattern of 23 design patterns - Java language-

Posted by wrapper on Sat, 20 Jun 2020 05:19:25 +0200

Factory model core and its classification

The core idea of the factory model: the separation of creators and callers
Classification:

  • Simple factory mode
  • Factory method mode
  • Abstract factory pattern

Simple factory mode

This pattern is the simplest way to manage object creation, because it simply encapsulates the creation of different class objects. This pattern specifies the object to be created by passing the type to the factory. Its UML class diagram is as follows:

Use mobile generation to explain the mode:
Phone class: mobile phone Standard Specification class (AbstractProduct)

public interface Phone {
    void make();
}

MiPhone class: manufacturing Xiaomi mobile phone (Product1)

public class MiPhone implements Phone {
    public MiPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi phone!");
    }
}

IPhone class: manufacturing Apple mobile phone (Product2)

public class PhoneFactory {
    public Phone makePhone(String phoneType) {
        if(phoneType.equalsIgnoreCase("MiPhone")){
            return new MiPhone();
        }
        else if(phoneType.equalsIgnoreCase("iPhone")) {
            return new IPhone();
        }
        return null;
    }
}

PhoneFactory class: cell phone Factory

public class PhoneFactory {
    public Phone makePhone(String phoneType) {
        if(phoneType.equalsIgnoreCase("MiPhone")){
            return new MiPhone();
        }
        else if(phoneType.equalsIgnoreCase("iPhone")) {
            return new IPhone();
        }
        return null;
    }
}

Use cases
Create objects through factories, not directly by callers

public class Demo {
    public static void main(String[] arg) {
        PhoneFactory factory = new PhoneFactory();
        Phone miPhone = factory.makePhone("MiPhone");            // make xiaomi phone!
        IPhone iPhone = (IPhone)factory.makePhone("iPhone");    // make iphone!
    }
}

Conclusion: when we add a Huawei mobile phone, we need to modify it in the PhoneFactory class (judge it, and then create a Huawei phone in new). Therefore, we can use the factory method mode for optimization.

Factory method mode

Compared with the simple factory model in which the factory is responsible for producing all products, the factory method model distributes the task of generating specific products to specific product factories, and its UML class diagram is as follows:

In other words, it defines an abstract factory, which defines the production interface of the product, but does not take charge of the specific product, and hands over the production tasks to different derived class factories. This eliminates the need to create objects by specifying the type.
Next, we will continue to use the example of manufacturing mobile phones to explain the mode.
The definitions of the Phone class, MiPhone class and IPhone class related to the product remain unchanged.
AbstractFactory class: an abstract class for factories that produce different products

public interface AbstractFactory {
    Phone makePhone();
}

XiaoMiFactory class: the factory that produces Xiaomi mobile phones (ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
}

AppleFactory class: the factory that produces Apple mobile phones (ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {
        return new IPhone();
    }
}

Use case:

public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        appleFactory.makePhone();        // make iphone!
    }
}

Conclusion: Although we have solved the problems left in the simple factory pattern, we can find that the class we wrote is much larger. Although we don't need to modify the code in the factory class, we need to re create a factory (for example, to create a Huawei factory - it needs to implement AbstractFactory class). In actual development, we don't necessarily think of factory method pattern It's better than simple factory model, because they have advantages and disadvantages, so we need to weigh them

Abstract factory pattern

No matter how the factory splits the abstraction, the above two patterns are only for one kind of product Phone (abstract product). If you want to generate another product PC, how should you express them?
The easiest way to do this is to make a complete copy of the factory approach described in 2, but this time it's a PC. But at the same time, it means that we need to completely copy and modify all the code of Phone production management. Obviously, this is a stupid way, which is not conducive to expansion and maintenance.
Abstract factory pattern adds an interface to create a product in AbstarctFactory, and implements the creation of new products in specific sub factories, provided that the sub factories support the production of the product. Otherwise, the inherited interface can do nothing.
Its UML class diagram is as follows:

PC class: define the interface of PC products (AbstractPC)

public interface PC {
    void make();
}

MiPC: define MiPC

public class MiPC implements PC {
    public MiPC() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi PC!");
    }
}

Mac class: define Apple computer products (MAC)

public class MAC implements PC {
    public MAC() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make MAC!");
    }
}

You need to modify the definition of factory related classes as follows:
AbstractFactory class: add PC product manufacturing interface

public interface AbstractFactory {
    Phone makePhone();
    PC makePC();
}

XiaoMiFactory class: increase the manufacturing of Xiaomi PC (ConcreteFactory1):

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
    @Override
    public PC makePC() {
        return new MiPC();
    }
}

AppleFactory class: add the manufacturing of Apple PC (ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {
        return new IPhone();
    }
    @Override
    public PC makePC() {
        return new MAC();
    }
}

Use case:

public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        miFactory.makePC();                // make xiaomi PC!
        appleFactory.makePhone();        // make iphone!
        appleFactory.makePC();            // make MAC!
    }
}

Topics: Mobile Mac