Factory method pattern is also called factory pattern. In the factory method mode, the factory parent class is responsible for defining the public interface for creating product objects, while the factory subclass is responsible for generating specific product objects. The purpose of this is to delay the instantiation of product classes to the factory subclass, that is, determine which specific product class should be instantiated through the factory subclass.
In short, instead of directly generating the corresponding specific products, we hand over the functions of the products to the factory. We just need to place an order with the factory.
The factory method model is generally divided into four parts:
Abstract creator role: this role is the core of the factory method pattern, which is independent of the application. Any factory class that creates objects in the pattern must inherit or implement this interface. In the actual system, this role is often implemented by Java abstract classes.
Concrete creator role: the concrete Java class that implements the abstract factory interface plays this role. Specific factory roles contain logic closely related to the application and are called by the application to create product objects.
Abstract product role: the supertype of the object created by the factory method pattern, that is, the common parent class or jointly owned interface of the product object. In practical applications, this role is often implemented by Java abstract classes.
Concrete product role: this role implements the interface declared by the abstract product role. Each object created by the factory method is an instance of a specific product role.
=========================================================================
Another example is the production of mobile phones:
------------------------------------------------
Suppose we have a factory to produce mobile phones. We have three kinds of mobile phones: Huawei P50, Xiaomi 12 and apple Iphone13 Pro Max.
At this time, let's think that instead of directly producing mobile phones, we hand over the production of mobile phones to a third-party OEM and let them produce mobile phones. In this way, we only need to send orders to the corresponding OEM to produce the corresponding mobile phones, and we don't need to know the production process of the OEM.
------------------------------------------------
Abstract factory role:
Corresponding to the parent class of the factory, it has the function of creating mobile phones.
package FactoryMethodPattern.factories; import Phones.Phone; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName Factory.java * @Description Factory abstract class * @createTime 2022 16:51:00, February 10 */ public abstract class Factory { /** *Create corresponding mobile phone * @return Return to create the corresponding mobile phone */ public abstract Phone createPhone(); }
Specific factory roles:
Inherit and implement the specific method of manufacturing mobile phones to manufacture the corresponding mobile phones.
Yinghuada OEM Xiaomi
/** * @author Zeyu Wan * @version 1.0.0 * @ClassName Envada.java * @Description Xiaomi generation factory * @createTime 2022 16:59:00, February 10 */ public class Envada extends Factory{ @Override public Phone createPhone() { return new XiaoMi11U(); } }
Flextronics OEM Huawei
package FactoryMethodPattern.factories; import Phones.HuaWeiP50; import Phones.Phone; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName Flex.java * @Description Huawei OEM * @createTime 2022 17:00:00, February 10 */ public class Flex extends Factory{ @Override public Phone createPhone() { return new HuaWeiP50(); } }
Foxconn OEM apple
package FactoryMethodPattern.factories; import Phones.IPhone13ProMax; import Phones.Phone; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName FoxConn.java * @Description IPHONE Foundry * @createTime 2022 16:57:00, February 10 */ public class FoxConn extends Factory { @Override public Phone createPhone() { return new IPhone13ProMax(); } }
Abstract product roles:
Like a simple factory, it corresponds to an abstraction of OEM products
package Phones; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName Phones.Phone.java * @Description Mobile phone Abstract square class. All abstract methods are implemented in subclasses * @createTime 2022 17:27:00, February 8 */ public abstract class Phone { /** *Call function abstract method */ public abstract void call(); /** *Abstract method of short message function */ public abstract void message(); /** *Game function abstraction method */ public abstract void game(); }
Specific product roles:
Implementation class of Xiaomi
package Phones; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName XiaoMi12.java * @Description Mi11U Implementation class of * @createTime 2022 17:03:00, February 8 */ public class XiaoMi11U extends Phone{ public XiaoMi11U(){ System.out.println("create XiaoMi11U"); } @Override public void call() { System.out.println("da....da.....da...."); } @Override public void message() { System.out.println("Message: Hello MIUI"); } @Override public void game() { System.out.println("WIFI ERROR"); } }
Huawei implementation class
package Phones; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName MiPhone.java * @Description Huawei implementation class * @createTime 2022 17:02:00, February 8 */ public class HuaWeiP50 extends Phone{ public HuaWeiP50(){ System.out.println("create HuaWeiP50"); } @Override public void call() { System.out.println("di...di....di...."); } @Override public void message() { System.out.println("Message: Hello Harmony"); } @Override public void game() { System.out.println("WeGame Start"); } }
Apple implementation class
package Phones; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName IPhone.java * @Description Iphone Implementation class of * @createTime 2022 February 17, 2008: 00 */ public class IPhone13ProMax extends Phone { public IPhone13ProMax(){ System.out.println("create iphone"); } @Override public void call() { System.out.println("du....du....du...."); } @Override public void message() { System.out.println("Imessage: Hello Iphone"); } @Override public void game() { System.out.println("IGame Start"); } }
Main function:
Under the main function, we don't need to know the production process and results. All we need to do is place an order with the OEM, and the OEM can manufacture the corresponding mobile phone
package FactoryMethodPattern; import FactoryMethodPattern.factories.Envada; import FactoryMethodPattern.factories.Factory; import FactoryMethodPattern.factories.Flex; import FactoryMethodPattern.factories.FoxConn; import Phones.Phone; /** * @author Zeyu Wan * @version 1.0.0 * @ClassName BuyPhone2.java * @Description Create through OEM * @createTime 2022 17:02:00, February 10 */ public class BuyPhone2 { public static void main(String[] args) throws Exception { //Input foundry String type = "FoxConn"; Factory factory = getByFactory(type); Phone phone = factory.createPhone(); phone.message(); } public static Factory getByFactory(String type) throws Exception { if (!type.isEmpty()) { switch (type) { case "FoxConn": return new FoxConn(); case "Flex": return new Flex(); case "Envada": return new Envada(); default: System.out.println("Create Error: Error Type"); throw new Exception(); } } else { System.out.println("Create Error: No Type Identify"); throw new Exception(); } } }
Mode advantages:
In the factory method mode, the factory method is used to create the product required by the customer. At the same time, it also hides the details of which specific product class will be instantiated from the customer. Users only need to care about the factory corresponding to the required product, do not need to care about the creation details, and even do not need to know the class name of the specific product class.
Polymorphic design based on factory role and product role is the key of factory method pattern. It enables the factory to determine which product object to create independently, and the details of how to create this object are completely encapsulated in the specific factory. The factory method pattern is also called polymorphic factory pattern because all concrete factory classes have the same abstract parent class.
Another advantage of using the factory method mode is that when adding new products to the system, there is no need to modify the interface provided by the abstract factory and the abstract product, the client, or other specific factories and specific products, but just add a specific factory and specific products. In this way, the scalability of the system becomes very good, which fully conforms to the "opening and closing principle".
Mode disadvantages:
When adding new products, it is necessary to write new specific product classes and provide corresponding specific factory classes. The number of classes in the system will increase in pairs, which increases the complexity of the system to a certain extent. More classes need to be compiled and run, which will bring some additional overhead to the system.
Considering the scalability of the system, it is necessary to introduce the abstract layer, which is defined in the client code, which increases the abstraction and understanding difficulty of the system. In addition, DOM, reflection and other technologies may be used in the implementation, which increases the difficulty of the implementation of the system.