当我们使用Singleton Pattern创建一个类时,我能够在同一个类中克隆。 这意味着违反了Singleton Pattern规则。任何人都可以澄清我的疑问。 我的代码是:
class SingletonObject implements Cloneable
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
SingletonObject obj = null;
if (ref == null){
// it's ok, we can call this constructor
ref = new SingletonObject();
try {
obj = (SingletonObject)ref.clone();
if(obj.equals(ref)){
System.out.println("both objects are same");
}else{
System.out.println("both objects are not same");
}
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return obj;
}
private static SingletonObject ref;
}
答案 0 :(得分:3)
来自Java SDK
一个类实现了Cloneable接口,以向Object.clone()方法指示该方法合法地为该类的实例创建一个字段的副本。
来自维基百科:
在软件工程中,单例模式是一种设计模式,用于通过将类的实例化限制为一个对象来实现单例的数学概念。
您使用clone()
违反了单身规则。它将创建你的单身人士的新实例。
答案 1 :(得分:2)
是的,如果您可以克隆单例,那么它不再是单例并且违反了模式。在您的情况下,您可以更改代码,以便在调用getSingletonObject
时抛出异常或委托给clone
。这将保留单例模式,但会破坏类的公共接口,也会打破客户的期望。
最好的解决方案是不实施Cloneable
。
答案 2 :(得分:1)
您可以保留Singleton特性并仍然通过定义简单返回相同实例的clone()方法的覆盖来实现Clonable
。但我不明白这一点。
克隆人和单身人士都是你应该在你真正需要的时候做的事情。我无法想象在同一个对象中需要两者的原因。
答案 3 :(得分:1)
克隆Singleton没有任何意义。所以一旦你允许克隆一个类,那么这个类就不再实现Singleton模式了。
你实际上克隆了一个名为Singleton 但不是Singleton的类。一旦克隆了类, class-named-Singleton 就不再是Singleton了。
答案 4 :(得分:0)
我建议你从最简单的模式开始,以满足你的需求。
enum SingletonObject {
INSTANCE;
}
你能说出为什么你的单身人士比这更复杂吗?
答案 5 :(得分:0)
很好的观察。您的代码是许多Java开发人员consider clone()
to be problematic:
这是一种绕过许多限制的机制,可以对创建对象进行限制。因此它可以用于复制单例。这(可以说)是Java的设计缺陷。唯一的解决方案是不使用clone
,或者不在您的班级中实施公开clone()
方法。
在实践中它并不是一个问题,因为clone
只有在类明确地实现它时才会起作用,而这对于单例来说是不行的。但它仍然很难看。