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就是服务提供者接口。
下面是书中给出的一个服务提供商框架的例子
A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. [/b](第四个优点是可以使创建参数化类型实例更佳简洁)
比如:创建HashMap时,就需重复输入类型参数
使用静态工厂方法可以解决这一问题
静态工厂方法也有一些不足之处:
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.
总体来说,静态工厂方法和构造器都有其自己的作用,但是一般说来还是优先使用静态工厂方法。
使用静态工厂方法有以下几点好处:
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.
总体来说,静态工厂方法和构造器都有其自己的作用,但是一般说来还是优先使用静态工厂方法。
相关文章推荐
- Effective Java 学习笔记(二)
- effective java 学习笔记(一) 2012-4-24
- Effective Java 学习笔记(一)
- Effective Java 学习笔记(4)
- Effective Java 学习笔记 (10)
- Effective Java 学习笔记(18)
- Effective Java 学习笔记 1
- Effective Java学习笔记 第61条: 抛出与抽象相对应的异常
- Effective Java 学习笔记(13)
- Effective Java 学习笔记(14)
- Effective Java 学习笔记(第46条:for-each循环优先于传统的for循环)
- Effective Java 学习笔记(第62条:每个方法抛出的异常都要有文档)
- Effective Java学习笔记 4 通过私有构造器增强不可实例化的能力
- Effective Java学习笔记---创建和销毁对象
- Effective Java学习笔记: 第58条 对可恢复的情况使用受检异常,对于编程错误使用运行时异常
- effective Java 学习笔记 (一)
- Effective Java 学习笔记 使用静态工厂方法代替构造器
- Effective Java-学习笔记(6-9章)
- Effective Java 学习笔记(9)
- Effective Java 学习笔记(第64条:努力使失败保持元子性)