This article describes the factory method pattern (Factory mode), in the actual development process we are used to directly use the New keyword to create an object, but sometimes the creation of objects requires a series of steps: You may need to calculate or get the initial settings of the object Choose which child object instance to generate, or you must generate some accessibility objects before generating the objects you need, this time you need to know the details of the object creation, that is, the place used is coupled with the implementation of the object, is not conducive to expansion, in order to solve this problem requires the use of our factory method pattern, It is suitable for scenes where complex objects are created, and the factory method pattern is also a highly used design pattern.
PS: The technology is interested in the same shoe plus group 5,446,459,721 Exchange.
Total catalog of design patterns
Java/android design mode Learning Notes directory
features
The factory method pattern (Factory) defines an interface for creating objects, but subclasses decide which class to instantiate, and the factory method defers the instantiation of the class to the subclass, which encapsulates the creation of the object in order to achieve a more loosely coupled, more resilient design.
Factory method mode is one of the creation design patterns, is a simple structure of a model, in our usual development process is also very extensive application, such as Arraylist,hashset, and Iterator can be regarded as a factory method.
Simple Factory is one of the factory method models, which summarizes the characteristics of the factory method model:
- The simple factory model is not really a design pattern in a sense, but it is still a simple way to decouple a client program from a specific class;
- The factory method pattern uses inheritance to delegate the creation of objects to subclasses, subclasses implement factory methods to create objects, that is, allow instantiation to be deferred to subclasses;;
- The factory method pattern is a very typical example of "programming for abstraction, not concrete class".
UML class Diagram
For the factory method model UML class diagram, the division of several roles is also very clear, mainly divided into four modules:
- The first is the abstract factory interface, which is the core of the factory method pattern, which defines the basic behavior of a factory class;
- The second is the concrete factory, it realizes the concrete business logic;
- Third, the abstract product interface, which defines the public behavior of all products;
- Four is the specific product, for the realization of an abstract product of a specific product object.
The difference between a simple factory model and a factory method pattern is that the simple factory model streamlines the role of the abstract factory interface, a weakened version of the factory method pattern.
From this design point of view, the factory method pattern is completely in line with the design principle, it encapsulates the creation of objects, in order to get more loosely coupled, more flexible design, and the factory method mode relies on the abstract interface, the instantiation of the task to the sub-class to complete, there is very good extensibility.
Example and source code
We take a simple toy factory, for example, the factory produces children's toys, girls ' toys and boys ' toys, first write a Itoy abstract product interface used to define the basic behavior of the toy model, and then implement the interface to generate a few toys specific product class Childrentoy,mentoy and Womentoy class:
Itoy.class
publicinterface IToy { /** * 名字 */ String getName(); /** * 价格 */ float price(); /** * 玩 */ void play();}
Childrentoy.class
Public class Childrentoy implements Itoy{ @Override PublicStringGetName() {return "Toy Car"; }@Override Public float Price() {return 10.5F }@Override Public void Play() {LOG.E ("Play","A child is playing a toy car"); }}
Mentoy.class
Public class Mentoy implements Itoy{ @Override PublicStringGetName() {return "PS4"; }@Override Public float Price() {return 2300; }@Override Public void Play() {LOG.E ("Play","A man was playing GTA5 on PS4"); }}
Womentoy.class
Public class Womentoy implements Itoy{ @Override PublicStringGetName() {return "Plush Toy"; }@Override Public float Price() {return $; }@Override Public void Play() {LOG.E ("Play","A woman is playing with a plush toy"); }}
After completing the two roles of the product, the next step is to define two roles for the factory class, which can be written in two different ways depending on the factory method pattern and the Simple factory model:
Factory Method
The factory method pattern needs to write out a factory class abstract interface to define the behavior, this time according to the actual situation we can divide into two kinds of realization way, the first kind of writing will have many concretefactory roles; the second is a concretefactory character. Different product objects are returned depending on the parameters passed in:
Multi Concreatefactory
Itoycreator.class
publicinterface IToyCreator { /** * 生产玩具 */ IToy createToy();}
Childrentoycreator.class
public class childrentoycreator implements itoycreator { private static final String TAG = " Childrentoycreator "; @Override public Itoy createtoy () {Itoy toy = new Childrentoy (); LOG.E (TAG, "buy a/an" + toy.getname () + "for" + Toy.price () + "yuan, and then---" ); Toy.play (); return toy; }}
Mentoycreator.class
public class mentoycreator implements itoycreator { private static final String TAG = " Mentoycreator "; @Override public Itoy createtoy () {Itoy toy = new Mentoy (); LOG.E (TAG, "buy a/an" + toy.getname () + "for" + toy. Price () + "yuan, and then---" ); Toy.play (); return toy; }}
Womentoycreator.class
public class womentoycreator implements itoycreator { private static final String TAG = " Womentoycreator "; @Override public Itoy createtoy () {Itoy toy = new Womentoy (); LOG.E (TAG, "buy a/an" + toy.getname () + "for" + to Y.price () + "yuan, and then---" ); Toy.play (); return toy; }}
Finally, you can create different Itoy objects directly as needed, and the test code is as follows:
Itoycreator Toycreator;Switch (v. GetId()) {case R. ID. BTN_child:toycreator = new Childrentoycreator ();Toycreator. Createtoy(); Break;Case R. ID. BTN_men:toycreator = new Mentoycreator ();Toycreator. Createtoy(); Break;Case R. ID. BTN_women:toycreator = new Womentoycreator ();Toycreator. Createtoy(); Break;}
Single concretefactory
Itoycreator.class
publicinterface IToyCreator { /** * 生产玩具 */ <T extends IToy> IToy createToy(Class<T> clazz);}
Concretetoycreator.class
Public class concretetoycreator implements itoycreator{ Private Static FinalString TAG ="Concretetoycreator";@Override Public<t extends Itoy> ItoyCreatetoy(Class<t> clazz) {if(Clazz = =NULL){Throw NewIllegalArgumentException ("argument must not being null"); }Try{Itoy toy = clazz.newinstance (); LOG.E (TAG,"Buy A/an"+ toy.getname () +"for"+ toy.price () +"Yuan, and then---"); Toy.play ();returnToy }Catch(Exception e) {Throw NewUnknownerror (E.getmessage ()); } }}
This kind of writing directly to a class object, and then using the reflection of the object creation, it can be said in a sense to streamline a lot of factory implementation class, without a specific product class corresponding to the need for a specific factory class, the following is the test code:
Itoycreator Toycreator;Switch (v. GetId()) {case R. ID. BTN_child:toycreator. Createtoy(Childrentoy. Class); Break;Case R. ID. BTN_men:toycreator. Createtoy(Mentoy. Class); Break;Case R. ID. BTN_women:toycreator. Createtoy(Womentoy. Class); Break;}
Summary Comparison
The two methods above are, of course, able to successfully print out the correct results:
The method of a single factory implementation class is more concise and dynamic than the previous methods of the factory implementation class, and for the future new product class can not modify the original code, in line with the open and closed principle, but this writing in some cases is not applicable, such as different Itoy Object set different constructors, parameters are not the same, with reflection to implement it is not applicable, this time can only be defined for each specific product class A corresponding specific factory class .
Simple Factory
The same is the code above, the specific factory implementation class only one time, we still provide an abstract class for the factory, then, if the role of Itoycreator is reduced, leaving only the role of Concretetoycreator, It should also be fine to set the product generation method to static:
Public classtoycreator{Private StaticFinal String TAG ="Toycreator"; Public Static<t extends Itoy> ItoyCreatetoy(Class<t> clazz) {if(Clazz = =NULL){Throw NewIllegalArgumentException ("argument must not being null"); }Try{Itoy toy = clazz.newinstance (); LOG.E (TAG,"Buy A/an"+ toy.getname () +"for"+ toy.price () +"Yuan, and then---"); Toy.play ();returnToy }Catch(Exception e) {Throw NewUnknownerror (E.getmessage ()); } }}
Such a way is called the Simple Factory model, which also said, is a weak version of the factory method mode, the disadvantage is that the loss of the quilt class inheritance characteristics, all the pressure is concentrated in the factory class, is not conducive to maintenance.
Summary
In general, the factory method pattern is a good design pattern, it follows a "as far as possible to keep things abstract" principle, loosely coupled design principles can also be well in line with the open and close principle, the instantiation of the class to subclass, but also rejected the shortcomings of the simple factory model.
But at the same time the factory method model also has some shortcomings, each time we add new products for the factory method to write a new product class, but also to introduce the abstraction layer, when the product type is very long, there will be a large number of corresponding factory objects, which will inevitably lead to complex class structure, so for the simple case, The use of the factory method model requires consideration of whether there is some "heavy".
Source Download
Https://github.com/zhaozepeng/Design-Patterns/tree/master/FactoryMethodPattern
References
http://blog.csdn.net/jason0539/article/details/23020989
Https://en.wikipedia.org/wiki/Factory_method_pattern
Http://news.tuxi.com.cn/to/kf/satmaj/namtst.html
Java/android Design Patterns Learning notes (3)---factory method mode