Use static factory method to replace construction method and static Construction
Create Object Construction Method create object
In Java, common methods to create objects areConstructorCreate;
For example, the following is a constructor of the Boolean class and a Boolean object is created using this constructor;
public Boolean(String s) { this(toBoolean(s)); }
Boolean bTrue = new Boolean("true");
Create object using static factory Method
In fact, there is another way to create an object, throughPublic static factory MethodBut this method is often ignored by programmers;
For example, the following is the valueOf method of the Boolean class and the Boolean instance returned by the static factory method. Note that no Boolean instance object is created here, but a previously created Boolean object is returned;
public static Boolean valueOf(String s) { return toBoolean(s) ? TRUE : FALSE; }
Boolean bTrue = Boolean.valueOf("true");
Differentiate static factory methods and factory method Modes
Note that the static factory method and the factory method mode in the design mode are not a concept:
- A static factory method usually refers to a static method in a class. You can call this static method to obtain an instance of this class;
- The factory method mode is a design mode that enables specific factory objects to be responsible for producing specific product objects. Multiple factories (classes) and objects (classes) are involved here ), for example, the memory factory produces memory objects, and the CPU factory produces CPU objects;
However, if we want to say something similar, the static factory method is similar to the simple factory model, but the difference is also quite big, in simple factory mode, the static factory method creates different objects (instances of different classes), while the static factory method generally creates only one instance of the class (including subclasses );
Advantages of using static factory methods 1. more readable
Suppose we need to write a class that generates the random number.RandomIntGenerator, which has two member attributes: min and max,
Suppose we need to create three typesRandomIntGenerator
Object,
1. Greater Than min, less than max;
2. Smaller than min than Integer. MAX_VALUE;
3. The value greater than Integer. MIN_VALUE is smaller than max.
If we do not use the static factory method, the code is generally designed as follows:
Class RandomIntGenerator {/*** minimum value */private int min = Integer. MIN_VALUE;/*** maximum value */private int max = Integer. MAX_VALUE;/*** smaller than min * @ param max */public RandomIntGenerator (int min, int max) {this. min = min; this. max = max;}/*** greater Than min is less than Integer. MAX_VALUE */public RandomIntGenerator (int min) {this. min = min;} // error: Duplicate method RandomIntGenerator (int) in type RandomIntGenerator // *** // * greater than Integer. MIN_VALUE is less than max // * // public RandomIntGenerator (int max) // {// this. max = max ;//}}
After observing the above Code, we found that the above Code is not only readable (new RandomIntGenerator (1, 10) and new RandomIntGenerator (10), but does not check the document, without reading comments, it is difficult to know the specific meaning of the object it creates.) In addition, when designing the last constructor, an error is returned because a working method with the same parameters already exists, the system prompts repeated definitions;
What if we use the static factory method:
Class RandomIntGenerator {/*** minimum value */private int min = Integer. MIN_VALUE;/*** maximum value */private int max = Integer. MAX_VALUE;/*** smaller than min * @ param max */public RandomIntGenerator (int min, int max) {this. min = min; this. max = max;}/*** greater Than min is less than max * @ param min * @ param max */public static RandomIntGenerator between (int min, int max) {return new RandomIntGenerator (min, max);}/*** greater Than min is less than Integer. MAX_VALUE */public static RandomIntGenerator biggerThan (int min) {return new RandomIntGenerator (min, Integer. MAX_VALUE);}/*** greater than Integer. MIN_VALUE less than max */public static RandomIntGenerator smallerThan (int max) {return new RandomIntGenerator (Integer. MIN_VALUE, max );}}
Successfully met the requirements: create three typesRandomIntGenerator
And the code is more readable than the constructor when creating an object;
2. You do not need to create a new object each time during the call.
The valueOf method of the Boolean class in JDK can well prove this advantage. In the Boolean class, there are two pre-created Boolean objects (True, False)
public final class Boolean implements java.io.Serializable, Comparable<Boolean>{ /** * The {@code Boolean} object corresponding to the primitive * value {@code true}. */ public static final Boolean TRUE = new Boolean(true); /** * The {@code Boolean} object corresponding to the primitive * value {@code false}. */ public static final Boolean FALSE = new Boolean(false);
When we call Boolean. when the valueOf ("true") method is used, the return value is the reference of the two instances. This avoids the creation of unnecessary objects. If the constructor is used, this effect cannot be achieved;
public static Boolean valueOf(String s) { return toBoolean(s) ? TRUE : FALSE; }
3. Any child type objects of the original return type can be returned.
// Public static Dog getInstance () {return new RedDog (); // or return new BlackDog ();}
4. Simpler code
Package tmp; class MyMap <K, V> {/*****/public MyMap () {} public static <K, V> MyMap <K, V> newInstance () {return new MyMap <K, V> () ;}} public class Main {public static void main (String [] args) {MyMap <String, string> map1 = new MyMap <String, String> (); // more concise. you can deduce MyMap <String, String> map2 = MyMap without specifying the type parameters. newInstance ();}}
Disadvantages of using static factory methods 1. If the class does not include the public or protect constructor, it cannot be inherited;
The following classes cannot be inherited by other classes;
class MyMap<K,V> { /** * */ private MyMap() { } public static <K,V> MyMap<K,V> newInstance(){ return new MyMap<K, V>(); }}
2. There is no difference with other common static methods. There is no clear identifier for a static method to be used to instantiate a class.
Therefore, a static factory method usually requires detailed comments and follows standard naming rules, such as using getInstance, valueOf, newInstance, and other method names;
Refer to the first article of self-explanatory java