我一直在玩一个有趣的想法(不知道我是否会将它包含在任何代码中,但考虑起来很有趣)
假设我们有一个需要大量类的程序,所有类都是某个子类。这些课程都需要单身。现在,我们可以为每个类编写单例模式,但是反复编写相同的代码似乎很浪费,而且我们已经有了一个共同的基类。创建A的getSingleton方法非常好,当从子类调用时,返回B类的单例(为简单起见,转换为A类)
class A{
public A getSingleton(){
//Wizardry
}
}
class B extends A{
}
A blargh = B.getSingleton()
A gish = B.getSingleton()
if(A == B)
System.out.println("It works!")
在我看来,这样做的方法是识别并调用B的默认构造函数(假设我们不需要传递任何内容。)我知道Java中反射的一些黑魔法,但是我我不确定是否可以这样做。
有人对此感到困惑吗?
答案 0 :(得分:2)
从技术上讲,我认为没有理由不能做到类似的事情。您的确切方案将无效,因为您的getSingleton
为static
(即使您未能如此声明),因此无法确定要调用的是哪个类。将其更改为static A getSingleton(Class cls)
,它可能是可行的。
然而,这真的是在每个派生类中都有一个单行getSingleton
的胜利吗?
对于初学者,您的getSingleton
会返回A
,因此,如果有人将其称为B
,则他们会返回A
并且必须向下转发以将其用作B
{{1}}。
此外,该计划并不完全透明。
当然,考虑一下会很有趣,但在任何生产系统中这样做之前我都会寻找更有说服力的理由。
答案 1 :(得分:2)
你可以用这种方式表示类:(实际上你可以使用所有类,如果他们有公共noargs构造函数)
//Code not tested
class A {
private static ConcurrentHashMap<Class,Object> instances=new ConcurrentHashMap();
private A(){}
public static <T> T getInstance(Class<T extends A> classe) {
Object instance=instances.get(classe);
if(instance==null) {
instance=createInstance(classe,instance);
}
return instance;
}
protected <T> T createInstance(Class<T> classe) {
return classe.getConstructor().newInstance();
}
}
答案 2 :(得分:1)
这是一个有趣的想法。减少重复代码的另一种方法是使用工具来处理“Singleton”的创建。在Java中执行此操作的常用方法是使用依赖注入工具(如Spring),它允许您定义要作为单例的所有类型,然后在需要时从Spring请求这些类型。 Spring然后确保它只创建所请求的每种类型之一。几乎没有代码重复。
这具有不强制类型本身的Singleton行为的好处。 Singletons的许多问题都围绕着他们因为全局状态而难以有效地测试代码的难度(我一直在项目中花费大量时间帮助人们弄清楚如何修复已被破解的测试两个不同的测试正在修改单例)。使用Spring可以获得类似行为的单例,但也可以选择在有意义的情况下创建单独的类型实例。
答案 3 :(得分:0)
答案是“不”,这是不可能的。
如果继承意味着“IS-A”,那么B就是A,它们不再是单身。
“......大量的类,都是某个子类。而那些类都需要是单例......”
我刚读完这篇文章。不是“大数”和“单身”矛盾吗?
就个人而言,我不想要维持这样的事情。我认为这是过度使用单身模式的一个例子,它接近于voted off the island at OOPSLA,而且过于聪明。
Google已编写utilities来识别其代码中的单身人士,以便将其删除。还想和你一起乱码吗?