单身人士在编程中的目的
这是一个相当宽松的问题。 我目前对单身人士的理解是,他们是以一种只有一个实例创build的方式build立的。
这听起来很像我的静态类。 主要区别在于,对于静态类,您不能/不能实例化它,只需使用它,如Math.pi()
。 单身课程,你仍然需要做类似的事情
singleton mySingleton = new singleton(); mysingleton.set_name("foo"); singleton otherSingleton = new singleton(); // correct me if i am wrong, but mysingleton == othersingleton right now, yes? // this the following should happen? otherSingleston.set_name("bar"); mysingleton.report_name(); // will output "bar" won't it?
请注意,我正在问这个语言,更多的是关于这个概念。 所以我并不担心如何编写这样一个类,而是更多地为什么你不想要和你需要考虑什么。
单一元素与静态类相比的主要优点是可以在以后轻松地决定实际上需要多个实例,例如每个线程一个实例。
然而,在实践中,单身人士的主要目的是使人们对于具有全局variables的感觉更less。
一个很好的使用单例的实际例子:你有一个使用SQL数据库的应用程序,你需要一个连接池。 这样的池的目的是重用数据库连接,所以你一定要所有的客户端使用相同的池。 因此,把它作为一个单例是正确的devise。 但有一天,你需要应用程序连接到第二个数据库服务器,并意识到你不能连接到同一个池中的不同服务器。 因此,你的“单一实例”单例变成“每个数据库服务器一个实例”。
你为什么不想
我不会因为单身人士通常是非常糟糕的方式来解决你的问题。 我向你推荐的是完全避免它们。
主要原因是:
- 单身大多数是全球性的(这是邪恶的)。
- 正确的dependency injection变得不可能。
我build议你在这个Google员工的博客中阅读其余的内容(包括详尽的解释):
当你想要一个单例服务的接口时,单例是非常有用的,但是直到运行时才会知道具体的类将被实例化。
例如,您可能需要声明一个中央日志logging服务,但只能在运行时决定是否挂钩文件logging器,存根logging器,数据库logging器或消息队列logging器。
一点知识是危险的东西,单身人士是危险的实体。 除了上面写的东西外,我可以强调Singleton对象的生命周期pipe理也很重要。 在ACE框架中,它被成功处理。 你可以在这里find这篇论文: http : //www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf
还请注意,单身人士应该是不可复制的课程。 这种模式似乎是最容易的模式,但相反却是困难之一。 因此,我要求考生对单身汉中的这个邪恶点进行说明。
像其他人一样说:
- 单身人士是另一个名字的全局variables。
- 单身人士通常是一个坏主意。
- 单身人士可以被“monostate”类别替代 – 这些类别显然具有正常的构造/破坏语义,但是都具有相同的状态。
请注意,在我看来,“静态类”通常也是一个坏主意,对于不允许使用自由函数的语言,或者在一堆函数之间共享状态而不希望将该状态作为parameter passing的问题,是一个骇人的解决方法。
根据我的经验,几乎所有使用单例或静态类的devise都可以通过摆脱这些构造变得更好,更容易理解,更灵活。
编辑:通过请求,为什么大多数单身人士是全球变数的另一个名字。
在我所知的大多数语言中,大多数单例类都是通过该类的静态成员函数来访问的。 所有可以访问单例类定义的代码都可以使用单实例。 这是一个全局variables – 包含该类的所有代码都可以对单例的单个实例进行修改。
如果不使用静态成员函数(或者具有相同含义的静态工厂方法),而是将单例对象传递给所有需要它的客户端,那么您将不需要单例模式,只需传递相同的反对所有客户。
除了其他的答案,我不得不说,当你想要一个静态类时,Singletons可以帮助你,但不能拥有它,因为由于你的应用程序的devise,它将inheritance一个可实例化的类。
有两种使用单身人士的方法。
- 他们应该使用的方式。 通常使用不可变variables(C#的String.Empty,Smalltalk中的类等)。 这大约是单身使用的1%。
- 作为全局variables的替代。 这不好。 造成这种情况的根本原因是人们想要分享共同的对象而不理解如何正确使用Builder。 以这种方式使用单例通常是对面向对象devise缺乏深刻理解的一个标志。
并不是所有的语言都有“静态类”(例如C ++没有它们)。
再一次用C ++的例子,向一个类添加静态variables是一个痛苦,因为你需要把它们放在头文件和.cpp文件中,所以在这种情况下,单例是非常有用的。
每种语言都不一样。 我猜在C#中它们不是很有用(事实上,据我所知,它们并不常用)
- 单例是全局variables的一个非常有用的替代,全部用在代码中。
- 单身人士通常不是“新”或“删除”d,他们倾向于初次使用,随程序范围一起删除
- 单件完全匹配包装日志logging,configuration和其他硬件接口类。