单例设计模式中私有构造函数的需求是什么?

时间:2016-03-15 07:52:22

标签: c# design-patterns singleton singleton-methods

当我浏览下面的代码时,我无法找到它在样本中使用私有构造函数的原因?

public sealed class Singleton
    {
        private static Singleton instance = null;
        private Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }

                return instance;
            }
        }
    } 

...

  //Why shouldnt I use something like below.
  public class Singleton
  {
       private static Singleton instance = null;            

       static Singleton()
       {
       }

       public static Singleton Instance
       {
            get
            {
                if (instance == null)
                {
                     instance = new Singleton();
                }

                return instance;
            }
        }
    } 

而不是公共类,如果我创建了一个静态类,我可以直接使用该类而不是创建实例。 当static关键字持久存在同一个作业时,在这里创建私有构造函数的需求是什么?

遵循这种模式的任何其他优势?

7 个答案:

答案 0 :(得分:3)

由于 Singleton 只能有一个实例,因此您必须阻止创建第二个实例。 如果你跳过构造函数声明,例如

  public class clsSingleTon {
  }

可以调用默认构造函数

  var one = new clsSingleTon();
  var two = new clsSingleTon(); // <- that's we try to ban

如果你声明构造函数是 public ,可以调用它,所以唯一的选择是 private 一个:

  public class clsSingleTon {
     public static int intcounter;

     // No-one will call it
     private clsSingleTon() {
     } 
     ...
  }

但是,您似乎根本不想要任何实例,因此删除构造函数并将该类声明为static

  // Static class - no instances are allowed 
  public static class clsSingleTon {
    //TODO: turn it into property
    public static int intcounter;

    public static void Hit() {
    }

    //TODO: turn it into property, do not mimic Java
    public static int getTotalHits() {
      return intCouner;
    }
  }

  ...

  clsSingleTon.Hit();
  MessageBox.Show(clsSingleTon.getTotalHits().ToString());

答案 1 :(得分:2)

单例类和静态类是不同的东西,似乎你正在混合它。静态类只有静态方法和静态成员,因此不能有构造函数。在类型上调用静态方法,而不是实例。

相反,单例类具有常规方法,并使用实例调用。私有构造函数用于防止创建类的多个实例,并且通常由返回此唯一实例的私有属性使用。

public class Singleton
{ 
    static Singleton s_myInstance = null;
    private Singleton()
    {
    }

    // Very simplistic implementation (not thread safe, not disposable, etc)
    public Singleton Instance 
    {
        get 
        { 
             if (s_myInstance == null) 
                   s_myInstance = new Singleton();
             return s_myInstance;
        }
     }
     // More ordinary members here. 
}

单身人士的优势在于他们可以实现接口。此外,如果它们是有状态的(具有许多成员),它们应该优于静态类,因为在静态类中具有许多静态字段是非常难看的设计。

答案 2 :(得分:0)

Singelton为您提供了实现接口的工具

Singelton pattren具有广泛的用途,你必须限制你的应用程序只创建一个实例,就像你只有一个实例的许​​多游戏一样

答案 3 :(得分:0)

在C#和.net之前设计了原始模式,请参阅http://www.blackwasp.co.uk/gofpatterns.aspx

Canonical实现是在c ++中,它没有静态类,因此你必须使用私有构造函数来控制类实例化

答案 4 :(得分:0)

有一个私有构造函数,因此只能在类中调用它。然后你必须定义一个静态方法,它将“锁定”你的类并实例化它。

答案 5 :(得分:0)

在理想的OOP世界中,您应该没有静态类。这是因为:

您不能拥有静态类的实例。这与大多数OOP原则和设计模式背道而驰。只需打开一个list of design patterns,逐个浏览它们,然后问问自己 - 我可以在没有课程实例的情况下这样做吗?如果答案是否定的 - 你就有优势在静态类上使用单例模式。

至于使用私有构造函数 - 请阅读answer by Dmitry Bychenko

答案 6 :(得分:0)

私有构造函数并不仅仅与单例类相关联。即使对于一个打算具有多个实例的类,使用公共构造函数也会导致分布式内存分配模型(即,对内存分配的控制权在任何可以调用'new()'的代码的手中)。相反,如果您具有私有构造函数和公共(静态)工厂方法,则可以集中进行内存分配。在许多情况下,您都使用私有构造函数。

  1. 您有一个实用程序类,该实用程序类仅公开静态util函数,例如,一个用于将其余模型转换为db模型,反之亦然的助手类,该类具有应用程序使用的所有String文字。由于所有方法/字段都是公共静态的,因此没有此类的对象的含义。

  2. 您只希望一个类的一个实例不是因为您试图节省内存,而是希望应用程序中的所有组件都使用同一实例,例如db连接管理器,内存中的缓存实现等。

来源:https://en.wikipedia.org/wiki/Singleton_pattern