? In object-oriented programming, the most common approach is to create an object instance from a new operator, which is used to construct an object instance. In some cases, however, the new operator directly generates the object, causing some problems. For example, the creation of many types of objects requires a series of steps: You may need to calculate or get the initial settings of the object; Select which child object instance to generate; Or, you must generate some accessibility objects before you can build the objects you need. In these cases, the creation of a new object is a "process", not just an operation, like a gear drive in a large machine.
Classification
The Factory mode is primarily to provide a transition interface for creating objects, so as to isolate the concrete process masks for creating objects for increased flexibility.
? The factory model can be divided into three categories:
- Simple Factory mode (Factory)
- Factory mode (Factory method)
- Abstract Factory mode (Factory)
? These three patterns are progressively abstracted from top to bottom and more general.
? In design mode, GOF divides the factory model into two categories: The Factory method Model (Factory) and the Abstract Factory mode (abstraction Factory). The simple Factory is seen as a special case of the factory method pattern, which is grouped into one category.
Simple Factory mode
In simple mode, the creation mode of the class is also called the Static Factory Method (Factory). The Simple factory model is a factory object that determines which product class instances are created. The purpose of its existence is simple: Define an interface to create an object.
Composition
- Factory class role: This is the core of this model, contains certain business logic and judgment logic. In Java it is often implemented by a specific class.
- Abstract product Role: It is generally the parent class or interface of the specific product inheritance. Implemented in Java by an interface or an abstract class.
- Specific product roles: the object created by the factory class is an instance of this role. Implemented in Java by a concrete class.
To give a simple example:
1 Abstract Product roles
publicinterface IProduct{ publicvoidmethod();}
2 Specific product roles (the method can be defined as static)
Public class producta implements iproduct{ @Override Public void Method() {System.out.println ("I ' m producta!"); }} Public class PRODUCTB implements iproduct{ @Override Public void Method() {System.out.println ("I ' m productb!"); }}
3 Factory class Roles
public class simplefactory{public iproduct produce (String Type) {if ( "A" . Equals (type)) { return new ProductA (); } else if ( "B" . Equals (Type)) {return new P RODUCTB (); } else {system. Out . println (); return null ; } }}
4 Test class
publicclass MainTest{ publicstaticvoidmain(String args[]) { new SimpleFactory(); IProduct product = factory.produce("A"); product.method(); }}
Output: I ' m producta!
? Java.text.DateFormat in Java is a typical case of a simple factory model.
Pros : Specifically defining a factory class is responsible for creating instances of other classes, the biggest advantage is that the factory class contains the necessary logic to dynamically instantiate the related classes according to the conditions the customer needs.
Cons : When you need to add a product, such as PRODUCTC need to modify the Simple factory class Simplefactory (increase If-else block), which violates the open and closed principle.
TIPS
In fact, if the use of reflection mechanism to implement a simple factory does not violate the open and closed principle.
Use the reflection mechanism to change the simple factory class to:
public class SimpleFactory{ public IProduct produce(Class<? extends IProduct> c) throws Exception { return (IProduct)Class.forName(c.getName()).newInstance();// return (IProduct)c.newInstance(); //或者采用这种方法 }}
? Test class:
publicclass MainTest{ publicstaticvoidmain(String args[]) throws Exception { new SimpleFactory(); IProduct product = factory.produce(ProductA.class); product.method(); }}
So when there is a new product, there is no need to modify the factory class. In effective Java (Second Edition), it is clear that generally, a normal application should not access objects in a reflective manner at run time. Therefore, this article is established in the case of no reflection mechanism, in the following introduction of the factory method model can also be used to implement the reflection mechanism, the blogger will not show. As for why effective Java (Second Edition) does not recommend a reflection mechanism, you can refer to the topic "Interface overrides the reflection mechanism" in this book, not to repeat it here.
Factory method Mode
? The factory method pattern is the further abstraction and generalization of the simple factory model, and the factory method pattern is no longer determined by a single factory class. The product class should be instantiated, and this decision is given to the subclass of the abstract factory.
? Look at its composition:
1. Abstract Factory Role: This is the core of the factory method pattern, which is not application-agnostic. is the interface that the specific factory role must implement or the parent class that must inherit. In Java it is implemented by an abstract class or interface.
2. Specific factory role: it contains code related to the specific business logic. Called by the application to create an object that corresponds to a specific product.
3. Abstract product Role: It is the parent of a specific product inheritance or an interface implemented. In Java, there are generally abstract classes or interfaces to implement.
4. Specific product roles: the object created by the specific factory role is an instance of this role. Implemented in Java by a specific class.
To give a simple example:
1 Abstract Factory role
publicinterface IFactory{ publicproduce();}
2 Specific Factory roles
Public class Concretefactorya implements ifactory{ @Override PublicIProductProduce() {return NewProductA (); }} Public class concretefactoryb implements ifactory{ @Override PublicIProductProduce() {return NewPRODUCTB (); }}
3 Abstract product roles (same as simple factory)
publicinterface IProduct{ publicvoidmethod();}
4 Specific product roles (same as simple factory)
Public class producta implements iproduct{ @Override Public void Method() {System.out.println ("I ' m producta!"); }} Public class PRODUCTB implements iproduct{ @Override Public void Method() {System.out.println ("I ' m productb!"); }}
5 Test Code:
publicclass MainTest{ publicstaticvoidmain(String[] args) { new ConcreteFactoryA(); IProduct product1 = factoryA.produce(); product1.method(); }}
Output: I ' m producta!
The difference in definition between the factory method pattern and the simple factory model is obvious. At the heart of the factory approach pattern is an abstract factory class, rather than a simple factory model that puts the core on a real class. The factory method pattern allows many real factory classes to inherit from the abstract factory class, which can actually become a synthesis of multiple simple factory models, thus promoting the simple factory model.
The advantage of factory method compared to the simple factory model is to add a product, only need to add a specific factory class and specific product class, did not modify the original factory class, in line with the opening and shutting principle. The disadvantage is that the client's code will need to be modified (the Simple Factory mode client does not need to be modified), and as the product continues to increase, the number of classes to be implemented will increase.
Abstract Factory mode
? in abstract Factory mode, an abstract product (abstractproduct) may be one or more, thus constituting one or more product families (products Family). In the case of only one product family, the abstract factory pattern actually degrades to the factory method pattern.
Factory method Mode VS Abstract Factory mode
? Factory Method Mode : An abstract product class that can derive multiple specific product classes. Each specific factory class can only create an instance of a specific product class.
? Abstract Factory mode : Multiple abstract product classes, each abstract product class can derive multiple specific product classes. An abstract factory class can derive a number of specific factory classes. Each specific factory class can create instances of multiple specific products.
? The difference : The factory method pattern has only one abstract product class, and the abstract factory pattern has multiple. Factory-mode-specific factory classes can only create instances of a specific product class, while abstract Factory mode may create multiple.
To give a simple example:
1 Abstract Product roles
publicinterface AbstractProductA{ publicvoidproduceA();}publicinterface AbstractProductB{ publicvoidproduceB();}
2 Abstract Factory role
publicinterface AbstractFactory{ publicCreateProductA(); publicCreateProductB();}
3 Specific Product roles
Public class ProductA1 implements abstractproducta{ @Override Public void Producea() {System.out.println ("Im producta1!"); }} Public class ProductA2 implements abstractproducta{ @Override Public void Producea() {System.out.println ("Im producta2!"); }} Public class ProductB1 implements ABSTRACTPRODUCTB{ @Override Public void Produceb() {System.out.println ("Im productb1!"); }} Public class ProductB2 implements ABSTRACTPRODUCTB{ @Override Public void Produceb() {System.out.println ("Im productb2!"); }}
4 Specific Factory roles
Public class ConcreteFactory1 implements abstractfactory{ @Override PublicAbstractproductacreateproducta() {return NewProductA1 (); }@Override PublicAbstractproductbCREATEPRODUCTB() {return NewProductB1 (); }} Public class ConcreteFactory2 implements abstractfactory{ @Override PublicAbstractproductacreateproducta() {return NewProductA2 (); }@Override PublicAbstractproductbCREATEPRODUCTB() {return NewProductB2 (); }}
5 Test Code
publicclass MainTest{ publicstaticvoidmain(String[] args) { new ConcreteFactory1(); AbstractProductA product1 = factory.CreateProductA(); AbstractProductB product2 = factory.CreateProductB(); product1.produceA(); product2.produceB(); }}
Output Result:
Im ProductA1!Im ProductB1!
The advantages of abstract Factory: Abstract Factory mode In addition to the advantages of factory method mode, the main advantage is that the product family can be constrained within the class. The so-called product family, generally more or less there is a certain association, the abstract factory model can be within the class to define and describe the relationship of the product family, rather than introducing a new class to manage.
The disadvantage of the abstract Factory: the expansion of the product family will be a very laborious thing, if the product family need to add a new product, then almost all of the factory class needs to be modified. Therefore, when using the abstract factory model, it is very important to classify the product hierarchy.
Factory methods in the JDK
Java.lang.object#tostring ();
Java.lang.class#newinstance ();
Java.lang.class#forname ();
Java.lang.boolean#valueof ();
Java.lang.proxy#newproxyinstance ();
Java.lang.reflect.array#newinstance ();
Java.lang.reflect.constructor#newinstance ();
Summarize
? Whether it's a simple factory model, a factory method model, or an abstract factory model, they all belong to the factory model and are very similar in form and feature, and their ultimate goal is to understand the decoupling. In use, we don't have to care whether this pattern is a factory method or an abstract factory pattern, because the evolution between them is often elusive. Often you will find that the factory method is clearly used, when the new requirements come, slightly modified, adding a new method, because the products in the class constitute a different hierarchical structure of the product family, it becomes an abstract Factory mode, and for the abstract factory model, when the reduction of a method of the provided products no longer constitute the product family, It evolved into a factory method model. Therefore, when using the factory model, it is only necessary to care whether the purpose of reducing coupling is achieved.
Resources:
1. "Design mode (i) Factory mode factory (created type)"
2. Learning: Java design mode-Factory mode
3.23 Design Modes (3): Abstract Factory mode
4. "Effective Java (Second Edition)" Joshua Bloch.
5. Design Patterns in the "digital JDK"
Design Patterns: Factory method Mode (Factory) and abstract Factory mode (Abstact Factory)