我有一个类,我想将其实例化限制为只有一个Factory类,如何防止这个对象被new运算符实例化?
答案 0 :(得分:4)
使所有构造函数包都是私有的;在同一个包中有一个Factory对象,它拥有包外的客户端的公共创建方法。
使用单个类很容易,但我想你要将该Factory视为虚拟:能够创建单个接口或抽象类的多个实现。
答案 1 :(得分:1)
您可以使类成为工厂类的内部(成员)类。单例工厂实例只能在工厂类中访问。工厂方法应该返回由内部类实现的公共接口。
public interface FooBehavior { ... }
public class FooFactory {
private static FooFactory factory = new FooFactory();
private FooFactory() { ... }
class Foo implements FooBehavior { ... }
public static FooBehavior createFoo() {
return factory.new Foo();
}
}
Foo
的实例与工厂的生命周期相关联。因为工厂的实例需要创建Foo
的实例,并且因为工厂的唯一实例包含在工厂中,所以只有工厂可以创建Foo
的实例。
另外,使用单例模式时要小心。
答案 2 :(得分:1)
根据你的问题,Jigar是正确的,但是,这是一种具有严重缺陷的反模式:
http://en.wikipedia.org/wiki/Singleton_pattern#Drawbacks
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
我建议您在实施此类解决方案之前先查看系统的设计。永远不需要以你所描述的方式锁定类的实例化。
答案 3 :(得分:1)
更简单的方法是信任同一个包中的其他类。
这样构造函数具有默认范围,而Factory必须位于同一个包中。
但是要回答你的问题,你可以使Factory成为一个内部类,它可以调用外部类的私有构造函数。 e.g。
public class MyObject {
private MyObject() { }
public static class Factory {
public MyObject create() {
// can call private members of the outer class.
return new MyObject();
}
}
}
MyObject.Factory mof = new MyObject.Factory();
MyObject mo = mof.create();
使用此方法限制对内部和嵌套类的访问。
答案 4 :(得分:0)
这并不容易。您可以将构造函数包本地化,然后将工厂置于同一个包中。这仍然意味着在同一个包中定义的类仍然可以实例化该类。
您可以通过执行类似 -
的操作来查询当前线程中的堆栈StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if ("your.package.Factory".equals(stackTrace[1].getClassName()) {
instantiateClass();
} else {
throw new InstantiationException("Can only instantiate from factory");
}
你必须检查它是哪个StackTraceElement,但这应该有效。
答案 5 :(得分:0)
另一种开始替换Singleton模式的模式是使用枚举:
public enum Factory { INSTANCE;
public SomeObject create(Params someParams) {
if (isTypeA(someParams))
return new TypeASubclass();
else if (isTypeB(someParams))
return new TypeBSubclass();
else
return new SomeDefaultObject();
}
}
您将以标准方式使用它:
SomeObject someObject = Factory.INSTANCE.create(myParams);
和enum
保证系统上只有一个工厂 *)
*)通常每个jvm /每个类加载器一个限制