4

当我浏览下面的代码时,我找不到它在示例中使用私有构造函数的原因?

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

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

遵循这种模式还有其他优势吗?

4

7 回答 7

5

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

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

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

单例的优点是可以实现接口。此外,如果它们是有状态的(有很多成员),它们应该优于静态类,因为在静态类中有许多静态字段是非常丑陋的设计。

于 2016-03-15T08:05:28.853 回答
3

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

  public class clsSingleTon {
  }

可以调用默认构造函数

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

如果您将构造函数声明为public,则可以调用它,因此唯一的选择是私有的:

  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());
于 2016-03-15T08:05:08.147 回答
0

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

  1. 您有一个实用程序类,它只公开静态实用程序函数,例如一个帮助类将其余模型转换为数据库模型,反之亦然,该类具有您的应用程序使用的所有字符串文字。由于所有方法/字段都是公共静态的,因此此类对象没有任何意义。

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

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

于 2019-01-09T15:41:03.370 回答
0

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

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


至于使用私有构造函数 - 阅读Dmitry Bychenko 的答案

于 2016-03-15T08:08:18.627 回答
0

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

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

于 2016-03-15T08:03:37.387 回答
0

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

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

于 2016-03-15T07:58:55.040 回答
0

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

于 2016-03-15T08:05:26.613 回答