There are two ways to get an instance of a Class 1. class provides a public constructor 2. class provides a public static factory method.
Advantages of the Static factory approach:
1. There is a name.
Careful selection of the method name can highlight the differences between multiple constructors, such as using the BigInteger (int, int, Random) constructor, and the returned BigInteger may be prime, if
Biginteger.probaleprime (int, Random) static Factory method, it is more clear.
2. It is not necessary to create a new object each time it is called.
The code in the Boolean class has public static final Boolean true = new Boolean (true) such a Ture constant, which initializes the constant when the class loads and returns each time in the ValueOf method
is the constant.
Public Static Boolean ValueOf (boolean b) {return (b? True:false);}
3. You can return an object of any subtype of the original return type. (polymorphic)
Java.util.EnumSet does not have a public constructor, only the static factory method, which returns one of the two implementation classes, depending on the size of the underlying enumeration type, if the element has 64 or fewer, returns a Regualreumset instance, with a single long support, and if more than 64, returns Jumboenum Set instance, supported with a long array.
Public Static<eextendsEnum<e>> enumset<e> noneof (class<e>ElementType) {Enum<?>[] Universe =Getuniverse (ElementType); if(Universe = =NULL) Throw NewClassCastException (ElementType + "not enum"); if(Universe.length <= 64) return NewRegularenumset<>(ElementType, Universe); Else return NewJumboenumset<>(ElementType, universe);}
Regularenumset with single long supportPrivate Longelements = 0L;
Jumboenumset supported with a long arrayPrivate LongElements[];
The two implementation classes Regualreumset and Jumboenumset are not visible to the customer, and the customer is only concerned that it is a subclass of some enumset, and if Regularenumset cannot provide performance benefits for small enumeration types, It is possible to remove it from a future release without any impact to the customer, and it will have no effect on the customer if the third, fourth, or even more enumset implementations are to be added in a future release.
A framework for a service provider:
//Service interfaces, implemented by service providers Public InterfaceService {//Service method ...}//Service Provider interface, implemented by the service provider Public InterfaceProvider {Service newservice ();}//a non-instantiated class for service registration and access to services Public classServices {PrivateServices () {}; //service Provider Name-mapping of the service provider Private Static Finalmap<string, provider> providers =NewConcurrenthashmap<string, provider>(); Public Static FinalString default_provider_name = "<def>"; //The service provider registers the API, which the system uses to register the implementation Public Static voidRegisterdefaultprovider (Provider p) {registerprovider (Default_provider_name, p); } Public Static voidRegisterprovider (String name, Provider p) {providers.put (name, p); } //service access API, which is used by customers to obtain service instances Public StaticService newinstance () {returnnewinstance (default_provider_name); } Public StaticService newinstance (String name) {Provider P=providers.get (name); if(p = =NULL) Throw NewIllegalArgumentException ("No provider registered with Name:" +name); returnP.newservice (); } }
The database connection service in conjunction with JDBC understands: Connection is the service interface, Drivermanager.registerdriver is the provider registration api,drivermanager.getconnection is the service access Api,driver is the service provider interface.
This implementation makes the Services class (in JDBC, that is, the DriverManager Class) code almost no need to modify (even if the modification will not change the framework, only optimize, the external interface will not change), and now a new database vendor, The vendor only needs to provide a service provider that implements the provider interface, and the service interface can be serviced, without any impact to the customer, because the customer does not know a new database at all.
4. Make your code more concise when you create a parameterized type instance.
New Hashmap<string, List<string>> ()
When invoking a parameterized type, it takes two times to supply the type parameter <string, list<string>>
If HashMap provides such a static factory:
Public static <k, v> hashmap<k, v> newinstance () { returnnew hashmap< K, v>();}
You can use
Map<string, list<string>> m = hashmap.newinstance ();
Instead of the old verbose code.
The main drawbacks of the static factory approach are:
1. If the constructor of a class is private, it cannot be quilt-like.
2. They are not actually any different from other static methods.
Like the Enumset class mentioned above, it does not provide a public constructor, so it is not possible to instantiate enumset s = new Enumset (), and at Eclipse it will prompt you that the class is not instantiated by the constructor, except that there is no useful message. It does not tell you to instantiate the object using a static factory method such as Noneof, AllOf.
1th: Consider replacing the constructor with a static factory method