仅将变量设为公共变量并访问实例时,创建getInstance()
有什么意义?
我知道抽象工厂设计模式对工厂有意义,因为我们在运行时决定所需的实现类型。
使用getInstance():
public class ClientFactory {
private static ClientFactory instance = null;
private ClientFactory() { }
public static synchronized ClientFactory getInstance() {
if ( instance == null ) {
instance = new ClientFactory();
}
return instance;
}
}
公开变量而不是创建实例方法:
public class ClientFactory {
public static final ClientFactory instance = new ClientFactory ();
private ClientFactory() { }
}
,我们可以使用ClientFactory.instance.foo();
轻松获得访问权限。
答案 0 :(得分:1)
后面的示例很热切-总是创建ClientFactory
。当可能性很小时,可能会使用ClientFactory
并且实例化它会很昂贵。
第一个是懒惰的。这意味着,当不使用ClientFactory
时,根本不会创建它。除了ClientFactory
是不可变的,而公共字段可以被覆盖。它的实例化也是安全的,因为它受到synchronized
的保护。
出于安全考虑,当客户调用以下行时(在第一种情况下):
ClientFactory.instance = null;
答案 1 :(得分:1)
使用getInstance()
之类的FactoryMethod可以为将来的更改提供更多选择。
例如
ClientFactory
演变为具有不同子级实现的抽象类),等等。答案 2 :(得分:1)
正如其他人正确指出的那样,这两种方法之间的主要区别在于,第一种方法将使用惰性实例化,而第二种方法将急于创建对象。应该将第二个方法中的ClientFactory
字段标记为final
,以避免让此类客户重新分配该字段。
第一种方法也使用synchronized
,这可能会对性能产生影响,因为在第一次成功分配字段后-以后就不需要同步了。因此,对于这种方法,您也可以将initialization-on-demand
与holder实例一起使用(因为您为单例使用静态字段):
public class ClientFactory {
private ClientFactory() { }
private static class ClientFactoryHolder {
private static final ClientFactory INSTANCE = new ClientFactory();
}
public static ClientFactory getInstance() {
return ClientFactoryHolder.INSTANCE;
}
}
它利用JVM类的初始化。如果有人调用ClientFactoryHolder.INSTANCE
方法,则ClientFactory.getInstance
字段将仅被初始化,因为类将在首次引用时进行初始化。还请注意,由于JVM会为我们负责,现在getInstance
方法不必同步。