[Negative tive Java distilled] item 1 considers replacing the constructor with the static factory Method

Source: Internet
Author: User
Tags protected constructor

About objective Java Distilled:

I have read this book tive Java for nearly two times on and off, and the content in it is very deep and helpful for improving the quality of engineering code. I'm going to sort out a series slowly. The reason why I name it "negative"
Java distilled is also intended to sort out the essence of the book as much as possible to facilitate review and use. After all, my memory is also very limited, and many things are often forgotten and I will give it a word, just take some reading notes for this book. The content in the article must be loyal to the original text. For some items, some content may be added, and I will mark the added content. At the same time, I hope this series of articles will help you. If you have any questions or suggestions, please leave a message. Thank you.


Outline:

  • What is the static factory method?
  • Static factory method declaration method
  • Advantages of static factory methods
  • Disadvantages of static factory methods
  • Disputes over static factory methods

 

What is the static factory method?

First, do not confuse static factory methods with several factory models in the design model. There is no inevitable association between the two. The static factory method is just a static method, which is used to return the current type (or its Subtypes) instance. The factory model involves more concepts. For more concepts, see related articles in the design patterns.

 

Of course, if you think about it, they also have something in common. They all aim to create objects more flexibly. In addition, when the return type declared by the static factory method is the interface type, the role of the static factory method is similar to the basic creation class design mode of the simple factory mode.

 

Static factory method declaration method

Why should we discuss the declaration method, because the Declaration method of the static factory method is almost the same as that of other static methods. Therefore, to identify or define a static factory method, we need to set some conventions manually. It is mainly reflected in the naming method. Several common naming methods are as follows:

Valueof, of, getinstance, newinstance, GetType, newtype, etc.

 

In the preceding method, the getinstance output rate is very high. In a singleton class, a getinstance method is often defined to return a unique instance of this type. The valueof and of methods are often used to parse input parameters and return corresponding instances based on them. These two methods are commonly used in multi-sample classes. The so-called multi-sample classes are classes with a limited number of instances, such as enumeration types, which are not unique. The most common example is the Boolean class, which defines a valueof method, accepts true and false of the string type, and then returns Boolean. True or Boolean. False. Newinstance is used in the reflection API. For example, you can obtain an instance of this class by calling the newinstance method on the class Object of the class.

 

In addition to the naming method, the method access modifier can be set as needed, which is consistent with the normal method. Generally, set it to public, because the main purpose of the static factory method is to be called to obtain the instance of the class.

 

In addition, since the static factory method is a common method, it must have a return value. Generally, the declared type of the returned value should be the type of the class where the static factory method is located.

 

Advantages of static factory methods

 

Of course, the advantages mentioned here are usually compared with those of traditional constructors.

 

Static factory method has name

Static factory methods have their own names, while constructors do not. This means that the same parameter list can only have one unique Constructor (by changing the order of parameters in the parameter list, you can have multiple constructor, but obviously, this is not a good idea ). In contrast, the static factory method does not have this restriction. For the same set of parameters, there can be any number of static factory methods. Therefore, in this case, the static factory method is used for Object Instantiation, which is more flexible and more readable.

 

More control over Object Instantiation

Once a constructor is called, a new instance is generated. The call to the static factory method is not necessarily. It only needs to return an instance of an object. It does not concern how the returned object is obtained. Therefore, the static factory method has more control over Object Instantiation. It can use the pre-created immutable object (immutable)
Instance), you can also obtain a frequently requested object from the cache. This greatly improves the performance.

 

The type of the returned object is more generalized.

The constructor can only return instances of the current class. The actual return type of the static factory method can be any child type of the declared return type. For example, to declare a static factory method of the base type, it can actually return the sub type, as long as the sub is a child type of the base. Because the concept of child types is not limited to inheritance layers, it can also be applied between interfaces and their implementation classes. Therefore, this generalized relationship also fits very well with the guiding principle of "interface-oriented programming.

 

The static factory method can use type Derivation

To instantiate a generic class, you may need to write very lengthy initialization statements, such:

Map <string, list <string> M = newhashmap <string, list <string> ();

 

In fact, this is still good. If you need to use a hashmap nested with several layers, it is really not easy to write the instantiation code for it. At this time, you can consider using the static factory method for one encapsulation, with its type derivation feature:

Publicstatic <K, V> hashmap <K, V> newinstance (){

Return new hashmap <K, V> ();

}

Then, use the following code to create an instance:

Map <string, list <string> M = hashmap. newinstance ();

 

Of course, for the use of type derivation in this scenario, whether it is good or bad, the good is that it does reduce the amount of code, but the bad aspect is also obvious, it is less readable and confusing.

 

For type derivation, we will introduce it in section 15.4.1 in Chapter 15th of "Java programming ideology, version 4.

 

Disadvantages of static factory methods

 

Static factory methods and common static methods are not differentiated

Without naming conventions, it is not easy to distinguish static factory methods from common static methods. At least it cannot be seen at a glance. Therefore, in the absence of support for Javadoc and built-in language features, it is very important to use reliable naming rules. The suggestions for naming are also described in the previous article.

 

Disputes over static factory methods

If only the static factory method is provided in a type, and the public or protected constructor is not provided, the type cannot be inherited. Inheritance depends on the constructor. This is because the constructor of the parent type is called when the sub-Type constructor is used.

 

Note that the previous word "only" does not occur unless it is specially designed, such as the collections class in Java Collection framework, only some static factory methods are included. This class is designed to be a class that cannot be instantiated, so it naturally has nothing to do with inheritance. For details, refer to item
4.


The declaration and implementation methods of the static factory methods contained in them are different from the above disputes. Do not confuse them. They are also briefly discussed here:

The objects created by these static factory methods are wrapper objects, such as the synchronizedlist method. It accepts a list object and returns a list object, the specific implementation of the returned list object is completely hidden. the visibility of the specific implementation class is at the package level, that is, the code outside the package is inaccessible and cannot be inherited, the summary code is as follows:


    public static <T> List<T> synchronizedList(List<T> list) {return (list instanceof RandomAccess ?                new SynchronizedRandomAccessList<T>(list) :                new SynchronizedList<T>(list));    }

The code above determines the specific implementation type by determining whether the list implementation can be accessed in sequence.

The so-called sequential access means that indexes can be used for access similar to arrays. In terms of the implementation of the list interface, the List Implementation classes that support sequential access include arraylist and arraydeque. The list interface implementation classes that do not support sequential access include sorted list, this is what we often call the linked list.

The following code is an internal static class at the packet access level instantiated when List supports sequential access. The reason why static classes are used here is that the instance of this class does not need to hold the reference of its container class. In this example, the container class is collections, which itself is a class that cannot be instantiated, therefore, it is reasonable to hold its reference. The types and usage of internal classes are described in items.

    static class SynchronizedRandomAccessList<E>extends SynchronizedList<E>implements RandomAccess {        SynchronizedRandomAccessList(List<E> list) {            super(list);        }SynchronizedRandomAccessList(List<E> list, Object mutex) {            super(list, mutex);        }

Note that this class inherits a class called synchronizedlist, which is inherited from the synchronizedcollection class, namely:

Synchronizedrandomaccesslist-> synchronizedlist-> synchronizedcollection


This inheritance layer is very familiar. The basic implementation classes in the Java collections framework are also based on this idea, namely:

Arraylist-> abstractlist-> abstractcollection


In fact, this is also an implementation strategy. The usage and benefits of this strategy will be discussed later when the combination is better than inheritance.

Go back to the discussion of the static factory method itself in a large circle:

The returned type of the synchronizedlist method is the list interface, rather than the implementation class such as synchronizedrandomaccesslist. This is because this implementation class does not provide any methods other than those defined in the list interface. Therefore, exposing this implementation class to the outside will not have any advantages, on the contrary, it will cause unnecessary troubles and cause unnecessary complexity. This also utilizes the advantages of the static factory method: 1) more control over type instantiation 2) the type of the returned object is more generalized (using interfaces instead of specific implementation classes)

 

In objective Java, this controversy is actually classified as one of the main drawbacks of the static factory method, but it seems that the author does not quite agree with this, as mentioned in the original article:

 

"

For example, it is impossible to subclass any of the convenience implementation classes in the collections
Framework. Arguably this can be a blessing in disguise, as it encourages programmers to use composition instead of inheritance.

For example, you cannot instantiate any implementation class in javacollections framework. But this is indeed a secret benefit because it encourages us to implement combinations rather than inheritance.

"

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.