我有一个抽象基类和一个实现类,如:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
//expected to return a singleton instance of clazz's class
}
public abstract absMeth();
}
public A extends Base
{
//expected to be a singleton
}
在这个例子中,我可以使A成为单例,甚至在Base中编写getInstance,为每次调用返回A的单例对象,这样做:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
try
{
return clazz.getDeclaredMethod("getInstance").invoke(null,null);
}
}
public abstract void absMeth();
}
public A extends Base
{
private static A inst;
private A(){}
public static A getInstance( )
{
if( inst!= null)
inst = new A();
return inst;
}
public void absMeth(){
//...
}
}
但我担心的是我如何确保如果有人写另一个类class B extends Base
它也应该是一个单例并且它必然实现一个名为getInstance的静态方法?
换句话说,我需要将此作为所有使用Base
类扩展的类的规范来强制执行。
答案 0 :(得分:3)
您无法信任扩展您的类来创建自己的单个实例 1 :即使您可以某种方式确保它们都实现getInstance
,也无法告诉其内部他们在构造自己的新实例之前检查inst
的方法。
保持对流程的控制:创建Map<Class,Base>
,并通过反射 2 实例化传入的类。现在,您的代码可以决定是否创建实例,而不依赖于子类的getInstance
。
<小时/> 1 一句流行的说法是,“如果你想做一份正确的工作,那就自己动手吧。”
2 以下是link描述基于setAccessible(true)
的解决方案
答案 1 :(得分:2)
Singleton是一种设计模式,而不是语言功能。通过语法以某种方式在继承树上强制执行它几乎是不可能的。
当然可以要求所有子类通过声明它abstract
来实现方法,但是无法控制实现细节。 Singleton是关于实现细节的。
但为什么这是一个关注呢?不要让您的应用依赖于别人代码的内部细节。它是Bad Design™并且有这个问题是它的确定标志。针对定义明确的接口的代码,避免依赖内部细节。