【问题标题】:Singleton Design Pattern-Java [duplicate]单例设计模式-Java [重复]
【发布时间】:2017-08-19 00:01:29
【问题描述】:

下面的类是否实现了单例模式?我真的很困惑。

class Customer {

    static private Map costumers = new HashMap();

    private Customer() {
    }

    public static Customer getInstance(String name) {
        Customer instance = (Customer) costumers.get(name);
        if (instance == null) {
            instance = new Customer();
            costumers.put(name, instance);
        }
        return instance;

    }
}

谢谢。

【问题讨论】:

标签: java design-patterns singleton


【解决方案1】:

不,它没有。除了线程安全和类型安全问题,我可以很容易地得到Customer 的两个不同实例:

Customer x = Customer.getInstance("first");
Customer y = Customer.getInstance("second");
System.out.println(x == y); // false

因此它不是单例。这是一种工厂/轻量级模式的混合体,但肯定不是单例模式。

【讨论】:

  • 没什么私人的,但我认为对此的支持量证明了Jon Skeet effect
【解决方案2】:

它不是。在给定的示例中,为每个不同的客户名称创建了一个新的客户实例。在单例的情况下不应该发生这种情况。应该为所有客户名称创建和共享一个客户实例。 Customer 实例需要是私有静态的,并且应该只创建和分配一次。

【讨论】:

    【解决方案3】:
    public class SingltonPattern {
    
    private static SingltonPattern instance = null;
    
    protected SingltonPattern() {}
    
    public static SingltonPattern getInstance() {
            if (instance == null) {
                    // Thread Safe - Second layer
                    synchronized (SingltonPattern.class) {
                            if (instance == null) {
                                    instance = new SingltonPattern();
                            }
                    }
            }
            return instance;
    }
    

    这是 Singlton DP 的一个模式。

    【讨论】:

    • 虽然很少需要双重检查锁定 - 在 Java 中实现线程安全的单例有更简单的方法。这也根本没有解决 OP 的代码。
    • @JonSkeet 虽然很少需要双重检查锁定 - 完全不同意(我们可以讨论它,但它在这里是题外话)。有更简单的方法可以在 Java 中实现线程安全的单例——正确的只是举了一个例子。这也根本没有解决 OP 的代码 - 我只是举了一个抽象的例子,所以 OP 可以找出他的问题。
    • 更简单的实现方式:单元素枚举,或者直接初始化instance变量。您很少需要这种更复杂且容易出错的模式。 (即使您希望能够在不初始化的情况下调用其他静态方法的懒惰,嵌套类也是一种更简单的方法。)如果您不解决 OP 的问题,它不属于该问题的答案,IMO .
    • 实际上,看到你有一个受保护的构造函数,这甚至不是单例模式的有效实现......
    【解决方案4】:

    单例设计模式是最简单的设计模式之一,它确保只能创建一个类的一个对象,并提供对该实例的全局访问点。

    它属于创建设计模式,因为它提供了一种创建对象的最佳方式。

    当我们只需要类的一个实例时,这很有用,例如一个由多个对象共享的单个数据库连接,因为为每个对象创建单独的数据库连接可能代价高昂。同样,应用程序中可以有一个配置管理器或错误管理器来处理所有问题,而不是创建多个管理器。

    class Singleton
    {
        private static Singleton instance;
    
        // private constructor to restrict the instantiation of Singleton Class
        private Singleton() {
    
        }
    
        //GetInstance method to provide global access to Singleton instance
        public static Singleton getInstance()
        {
            if (instance==null)
                instance = new Singleton();
            return instance;
        }
    }
    

    Refer the post for more details

    【讨论】:

      猜你喜欢
      • 2018-02-03
      • 2011-11-21
      • 1970-01-01
      • 2011-06-25
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 2012-08-19
      相关资源
      最近更新 更多