Item 1: Consider static factory methods instead of constructors (多考虑使用静态工厂方法而不是构造方法)
使用静态工厂方法有以下几点好处:
One advantage of static factory methods is that, unlike constructors, they have names.(一个好处是与构造方法不同,静态工厂方法有名字)。 使用静态工厂方法可以说明客户程序员理解程序。因为静态工厂方法可以去一些比较有意义的名字使代码可读性更高。比如
BigInteger(int, int, Random) 这个构造方法是返回一个很有可能是质数的BigInteger, 从这个构造方法 根本不能很明确的得到这一信息。这时候可以采用一个静态工厂方法来说明理解,如BigInteger.probablePrime。 静态方法的名字 probablePrime 很明确地告诉了客户程序员这个方法是干什么的。
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked. (第二个好处是,与构造方法不同,静态工厂方法不需要再每次被调用的时候创建一个新的对象,这个类似于设计模式中的Flyweight 享元模式)
静态工厂方法可以在多次调用的时候返回同一个对象,可以让类严格地管理它的实例(什么时候应该销毁,什么时候应该创建等等)。这种类可以叫做 instance-controlled. Instance control可以让类实现单例(Item 3),不可实例化(Item 4)等等的特殊需求。它同样允许,不可变类(Item 15)的实现 以保证没有两个相同实例 存在。 那么也就意味着 a.equals(b) 当且仅当 a==b的时候成立。所以客户程序员可以使用==代替 equals方法,这样可以提高程序的运行效率。
A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.(使用静态工厂方法,与构造方法不同,可以返回其返回类型的任意子类型)
这一优点保证了程序的灵活性,这也是service provider frameworks(服务提供商框架)的基础之一。
服务提供商框架一共有四个部分组成:
1. Service interface:服务接口,通过抽象统一声明,由服务提供者实现。
2. provider registration API:服务提供者注册API,用于系统注册服务提供者,使得客户端可以访问它实现的服务
3. Service access API:服务访问API,用户客户端获取相应的服务。
4. Service provider interface(Optional): 服务提供者接口,这些服务提供者负责创建其服务实现的实例。
对于JDBC来说,Connection就是服务接口,Orcale、SQLServer、MySQL等是服务提供者,它们实现相应的服务接口;DriverManager.registerDriver是提供者注册API,向DriverManager注册给定驱动程序;DriverManager.getConnection是服务访问API;Driver就是服务提供者接口。
下面是书中给出的一个服务提供商框架的例子
- // Service provider framework sketch
- // Service interface
- public interface Service {
- ... // Service-specific methods go here
- }
- // Service provider interface
- public interface Provider {
- Service newService();
- }
- // Noninstantiable class for service registration and access
- public class Services {
- private Services() { } // Prevents instantiation (Item 4)
- // Maps service names to services
- private static final Map<String, Provider> providers =
- new ConcurrentHashMap<String, Provider>();
- public static final String DEFAULT_PROVIDER_NAME = "<def>";
- // Provider registration API
- public static void registerDefaultProvider(Provider p) {
- registerProvider(DEFAULT_PROVIDER_NAME, p);
- }
- public static void registerProvider(String name, Provider p){
- providers.put(name, p);
- }
- // Service access API
- public static Service newInstance() {
- return newInstance(DEFAULT_PROVIDER_NAME);
- }
- public static Service newInstance(String name) {
- Provider p = providers.get(name);
- if (p == null)
- throw new IllegalArgumentException(
- "No provider registered with name: " + name);
- return p.newService();
- }
- }
A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. (第四个优点是可以使创建参数化类型实例更佳简洁)
比如:创建HashMap时,就需重复输入类型参数
- Map<String, List<String>> m = new HashMap<String, List<String>>();
使用静态工厂方法可以解决这一问题
- //静态工厂方法,类型参数只需要在这里写一遍即可
- public static <K, V> HashMap<K, V> newInstance() {
- return new HashMap<K, V>();
- }
- //创建对象时,就不用重复类型参数了。
- Map<String, List<String>> m = HashMap.newInstance();
静态工厂方法也有一些不足之处:
The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed(最大的缺点是,如果类只提供了静态工厂方法而没有提供public和protected的构造器的话,不能派生子类)
A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods. (第二个缺点就是使用静态工厂方法,客户程序员从文档中很难将其与其他静态方法区别开来)第二个缺点涉及到javadoc,因为javadoc不会对静态工厂方法进行特殊处理,所以客户程序员不能像查询构造方法一样 很快的找到静态工厂方法。
以下是一些常用的静态工厂方法的命名方法:
• valueOf—Returns an instance that has, loosely speaking, the same value as its
parameters. Such static factories are effectively type-conversion methods.• of—A concise alternative to valueOf, popularized by EnumSet (Item 32).
• getInstance—Returns an instance that is described by the parameters but
cannot be said to have the same value. In the case of a singleton, getInstance takes no parameters and returns the sole instance.• newInstance—Like getInstance, except that newInstance guarantees that
each instance returned is distinct from all others.• getType—Like getInstance, but used when the factory method is in a different
class. Type indicates the type of object returned by the factory method.• newType—Like newInstance, but used when the factory method is in a different
class. Type indicates the type of object returned by the factory method.总体来说,静态工厂方法和构造器都有其自己的作用,但是一般说来还是优先使用静态工厂方法。
转载于:https://blog.51cto.com/befenghan/1132351