单身人士是违反还是不违反?

时间:2011-06-06 11:16:13

标签: java design-patterns

当我们使用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;
}

6 个答案:

答案 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只有在类明确地实现它时才会起作用,而这对于单例来说是不行的。但它仍然很难看。