您的位置:首页 > Web前端

Effective Java 学习笔记 1

2013-02-06 01:25 323 查看
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. [/b](第四个优点是可以使创建参数化类型实例更佳简洁)

比如:创建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[/b](最大的缺点是,如果类只提供了静态工厂方法而没有提供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.
总体来说,静态工厂方法和构造器都有其自己的作用,但是一般说来还是优先使用静态工厂方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: