私人构造函数在单例设计模式中需要什么?

问题描述:

当我通过下面的代码,我无法找到它在示例中使用私有构造函数的原因?私人构造函数在单例设计模式中需要什么?

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; 
      } 
     } 
    } 

,而不是公共类,如果我创建了一个静态类,我可以使用类,而不是直接创建实例。 当静态关键字一直存在于同一个工作中时,需要在这里创建一个私有构造函数吗?

遵循此模式的其他优点?

+0

https://www.michaelsafyan.com/tech/design/patterns/singleton – Idos

+0

这不是一个单身人士,没有实例方法。私人构造函数只是防止客户端代码创建一个实例(这不需要任何东西)。类的静态修饰符仅在C#2中引入 - 也许代码早于此,否则作者不知道它。 –

+0

我已经更新了代码。 –

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

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

原审模式是在C#和.net之前设计的,请参见http://www.blackwasp.co.uk/gofpatterns.aspx

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

由于单身人士可以有只有一个实例,你必须防止二次创建。 如果你跳过构造函数声明,例如

public class clsSingleTon { 
    } 

一个可以调用默认构造函数

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

如果声明构造函数是公共,可调用它,那么唯一的选择就是私人之一:

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()); 
+0

对不起..我不清楚你想传达什么..我的问题是创建一个静态类而不是私有构造函数是错误的。正是你在最后一个片段中所做的。 –

+0

@Ammu:在你当前的实现中(取自Java?)你*没有静态类(Java不允许静态类),因此防止实例创建的唯一选择是隐藏构造函数。在C#*静态类*是最好的实现(无*锅板*代码);另一个问题是结合'intcounter'和'getTotalHits()'到*属性* –

+0

@ Dmitry Bychenko结合intcounter和getTotalHits的需要是什么?为什么我不能像你在答案中提到的那样使用相同的方式? –

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

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

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

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. 
} 

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

+0

请注意,你的实现是最简单的,因此不是线程安全的,或者提供一个标准的线程安全版本。 –

+1

好的。这个问题非常基本,我认为更喜欢真正的基本实现。 – PMF

+0

为什么不能在你给出的代码中使用静态构造函数作为例子?也只会调用一次。 –

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

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


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