×

消息

EU e-Privacy Directive

This website uses cookies to manage authentication, navigation, and other functions. By using our website, you agree that we can place these types of cookies on your device.

View e-Privacy Directive Documents

You have declined cookies. This decision can be reversed.

做Java有七、八年了,行业经典著作似乎一部都没有完整啃下来过,实在惭愧。就从名气最大的一部非入门级作品开始吧,Effective Java第二版。边读边记下一个脱水版,方便以后查阅。

静态工厂方法(static factory method)优于构造函数(constructor)

真是不习惯把这些术语翻译成中文,以后还是记原文好了。

static factory method代替构造函数的最简单例子:

Integer.valueOf(42)

Static factory method相对于constructor的好处:

1.有方法名,便于区分不同的方法

比如一个类

class MobilePhone {
	private boolean isSmart = false;
	private String os;

	public MobilePhone() {
	}

	public MobilePhone(String _os) {
		os = _os;
		isSmart = true;
	}
}

这个类的两个constructor的区分,对使用者来说不是很清楚,经常需要看文档或代码才能明白。如果换成static factory method,就会好很多:

class MobilePhone {
	private boolean isSmart;
	private String os;
	private static final String NON_OS = "NON-OS";

	private MobilePhone() {
	}

	public static MobilePhone createSmartPhone(String _os) {
		MobilePhone obj = new MobilePhone();
		obj.os = _os;
		obj.isSmart = true;
		return obj;
	}

	public static MobilePhone createFeaturePhone() {
		MobilePhone obj = new MobilePhone();
		obj.os = NON_OS;
		obj.isSmart = false;
		return obj;
	}
}

2.不是必须创建新对象(object)

想法类似于Singleton的对象管理,可以控制对象的创建数量,增进性能。需要注意,这种应用中类通常被要求是不可变的(immutable) 

很简单的例子就是Boolean类的创建方法:

public static Boolean valueOf(boolean b) {
	return b ? Boolean.TRUE :Boolean.FALSE;
}

用这一方法取得的Boolean对象,在内存中永远只有两个:Boolean.TRUE和Boolean.FALSE。极端一些的用法,把构造函数完全禁用,保证了相互equal()对象的唯一性之后,可以用==代替equals()来验证对象是否相等。

3.可以返回任何子类的对象

把接口作为static factory的返回类型,实际可以返回这一接口的任意实现。典型应用就是JDBC API:

public interface DataSource extends CommonDataSource,Wrapper {
  Connection getConnection() throws SQLException;
  Connection getConnection(String username, String password) throws SQLException;
}

取决于所配置的jdbcDriver类型,两个getConnection()方法可以返回各种各样的jdbc连接:Oracle、MySQL、Postgre...

4.对泛型(generic types)对象的创建,减少代码复杂度

Map<String, List<String>> m = new HashMap<String, List<String>>();

 可以被简化为:

Map<String, List<String>> m = HashMap.newInstance();

坏处:

1.只提供static factory method的类,如果没有公共或受保护constructor,无法继承

2.不容易和其他静态方法作区分

尽量使用约定俗成的方法名:valueOf、of、getInstance、newInstance等等

结论是,static factory method完胜,在任何需要提供公共constructor的场合,都应更优先考虑static factory method。

提交评论


安全码
刷新