为什么我需要Singleton设计模式?

我尝试学习设计模式,但真的很难理解OOD的主要思想。 我用经典方法创建了我的软件。 另一方面,我想学习OOD。 为什么我需要单身人士和其他人? 我编写了一些简单的程序:其中一个是clasical(我的风格),另一个是singleton模式。请教我为什么需要单身。 我的方法比它更好更清晰:)

我的风格:(C#)

public partial class Singletonsuz : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Loadbalancer balancer = new Loadbalancer(); for (int i = 0 ; i < 15 ; i++) { string server = balancer.Server; Response.Write("Dispatch Request to: " + server); } } } class Loadbalancer { private List _servers = new List(); private Random _random = new Random(); public Loadbalancer() { _servers.Add("ServerI"); _servers.Add("ServerII"); _servers.Add("ServerIII"); _servers.Add("ServerIV"); _servers.Add("ServerV"); } public string Server { get { int r = _random.Next(_servers.Count); return _servers[r].ToString(); } } } 

辛格尔顿:

 public partial class SingletonDP2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { LoadBalancer balancer = LoadBalancer.GetLoadBalancer(); for (int i = 0; i < 15; i++) { string server = balancer.Server; Response.Write("Dispatch Request to: " + server ); } } class LoadBalancer { private static LoadBalancer _instance; private List _servers = new List(); private Random _random = new Random(); private static object syncLock = new object(); protected LoadBalancer() { _servers.Add("ServerI"); _servers.Add("ServerII"); _servers.Add("ServerIII"); _servers.Add("ServerIV"); _servers.Add("ServerV"); } public static LoadBalancer GetLoadBalancer() { if (_instance == null) { lock (syncLock) { if (_instance == null) { _instance = new LoadBalancer(); } } } return _instance; } public string Server { get { int r = _random.Next(_servers.Count); return _servers[r].ToString(); } } } } 

设计模式不是设计或开发方法 。 它们是一个词汇表 :它们有助于将名称放在软件架构中出现的重复模式上。 根据我的经验,设计软件FROM模式最终会出现在多毛的软件中,并且有许多单一用途的类,这增加了程序员必须考虑的事情数量(并且软件开发很复杂,足以避免让你的大脑充满噪音)。

然而,设计模式在后期非常方便。 始终从您的特定问题和域开始,尝试找到解决方案,并确定流程中的模式。 不要从模式开始,试图强迫你的问题。 了解最常见的模式是必须的,因为它可以简化程序员(无论是开发人员还是图书馆用户)之间的沟通,并促进良好实践。

例如,假设您的问题涉及数据集。 在某些时候,您已经构建了数据结构和算法。 现在,您(或其他人)需要以更高级别的方式访问您的数据。 这是迭代器或访客模式可以应用的典型情况。 这就是在C ++ STL中完成的方式,其中所有集合类都理解迭代器。 但是,您不需要预先考虑您可能或可能不适用于此处或那里的模式,一旦确定了模式或需求,总会有时间重构事物。

设计模式最初来自建筑和架构,它们在很多方面与软件开发非常相似。 根据我的经验,理解DP的最佳方式是通过类比建筑:软件是建筑,模式是建筑元素的组织方式:窗户,门,走廊,楼梯,灯……建筑师不考虑他们的元素想要使用,但想想他们想要得到的效果。 例如,建筑师可能会想:这个楼梯需要光线。 为了达到这个目的,他可以根据建筑限制,建筑规范,客户的品味等使用窗户,天窗,玻璃砖,人造灯等。在考虑他试图解决的问题之前,他不会随意选择元素。解决,除非他试图达到效果或风格。 此外,如果市场上有另一种解决方案(例如反光阳光隧道),那么他可以将其整合到他未来项目的可用设计模式中。 OTOH如果他在考虑问题之前习惯于考虑解决方案,他就会冒险错过替代解决方案,使问题复杂化,或根本不解决问题。

在这里,您已经将Singleton模式用于需要动态初始化的全局对象。 在这种情况下,Singleton是一个可接受的解决方案。 但是,由于外部约束(例如,您需要按特定顺序初始化对象),有时您需要更复杂的解决方案,而Singleton将不再合适。 或者对象只需要静态初始化,并且普通的全局变量可以满足您的需求。

过度使用设计模式与在需要它们的地方不使用它们一样糟糕。 选择是否使用某种模式需要具备软件设计和开发方面的知识和经验,特别是您的领域。

你真的不需要模式。 您需要的是解决具体问题的方法。 模式只是众所周知的问题的通用解决方案,因此被认为是好的和有效的解决方案。

模式的问题在于您可以轻松地找到自己在解决方案中寻找问题。 即你开始搜索适合问题的模式,当你应该反思时:想想问题,然后尝试你的解决方案是否符合模式。

当你有一把锤子时,一切看起来像钉子……

Singleton模式被广泛认为并非真正的模式。 它更像是一个人如何呈现模式的例子。

您可能会发现更常用的模式(如访问者 )更有用。

单身人士通常只是用来certificate一些全球国家的存在。

如果你有全局状态接受它并且不觉得需要将它包装在像singleton这样的模式中,除非在以下有限的情况下:

您正在从图书馆展示这个全球状态。

如果您将其公开为普通的公共静态字段,那么改变您依赖全局状态(可能发生的事情)的决定可能变得非常困难。

在那些情况下,将外部世界的价值呈现为不是单身人士,而是作为默认情况 ,恰好是静态定义将允许设计的变化(并且不鼓励API的用户将其视为仅仅是唯一的实例)。

这实际上只是您目前正在实施的工厂

因此,构造的“隐藏”是重要的部分,而不是返回值的全局性质。

如果类的使用者是同一构建过程的一部分(即如果以某种方式更改类,受影响的代码将直接受到下一个构建的影响)那么需要进行此包装以允许更改是没有实际意义的因为你可以根据需要直接改变它。 这是“你不需要它”指南的应用。

Singleton Pattern是官方认可的在现代OOP语言中做类似于全局变量的方法。 这可以防止全局变量名冲突等等,因为它与类隔离,因此更容易避免重复的类名(因为编译器会出错)。 使用“延迟实例化”创建对象也更容易:您可以在单例函数中等到第一次需要对象时进行实例化。 从长远来看,这可以节省一些CPU周期。

设计模式用于在大型代码库中构造代码。 不是每个程序员都使用自己的编码风格,而是从左到右连接系统,而是使用适合您正在开发的应用程序的设计模式。 设计模式基本上说明了如何构建代码,以及不同系统应如何相互交互。

设计模式的使用可以加快开发时间,并可能迫使您以一种可以防止进一步出现问题的方式进行思考。 如果您想在现场工作,学习或至少了解多种设计模式至关重要。 一个拥有大型软件项目的公司,如果你开始像一些牛仔一样编写代码,打破并破坏所选择的习惯用法,那么就会对你有所了解。 因为这会使团队中的其他开发人员感到困惑,并且通常会使事情变得更难理解。

当你向其他人提供代码/库时,单身人士更适合……

您的第一个示例允许多个实例,因此不遵循单例模式。

第二个示例不允许多个实例…在第一个示例中使用公共构造函数允许LoadBalancer的多个实例。 因为它在第二个示例中受到保护(私有),并且调用者必须使用“GetLoadBalancer”来检查现有实例,所以它只强制执行一个副本。

好吧,你需要知道使用最重要的东西的顾客在哪里不是特定于上下文的代码如果你想确保在你的应用程序中单个访问对象的方法和属性,可以使用单例。 例如,在处理对数据库中表的访问的类中使用。 然而,即使你真的不需要它们,单身人士也会在应用程序中传播

在您的示例中,只有一个LoadBalancer实例并没有什么好处。 这使得理解Singleton可能带来的好处变得更加困难。

示例中的LoadBalancer只返回随机服务器。

想象一下一个Loadbalancer类,它跟踪他/她已经返回的服务器,这样LoadBalancer可以返回负载最小的服务器。

在这种情况下,所有Singletonsuz实例都需要与同一个LoadBalancer进行通信:如果它们都只是创建自己的(它不知道其他LoadBalancers做了什么),那么就没有真正的平衡并且跟踪返回的服务器会没用

如果他们都需要与同一个实例进行通信,他们可以调用静态GetLoadBalancer,然后该单个实例可以返回已经返回最少次数的服务器。

希望这可以帮助

一月

就面试问题而言,这是最着名的设计模式之一。

想象一下G + 4楼的建筑。 每层楼都有2个单位,共有8个单位。 每个公寓平均有4名成员,使用电梯最少有32名成员。

现在考虑一个8层楼的办公楼。 每层至少有5个办公室,每个办公室的员工数量从不受限制。

在第一个场景中,我们不需要多个电梯。 在第二种情况下,单个电梯是不够的。

现在您已经了解了单个升降机的需要与多个升降机的需求。 这为我们理解Singleton设计模式奠定了基础。

SINGLETON设计模式

就像前面示例中的电梯一样,Singleton设计模式也用于创建和使用对象的一个​​实例。

为什么? 因为应用程序不需要多个对象。

如果您已经看过专业办公室,您会发现一层楼的所有员工共享一台打印机。 所有的学生都没有把打印机留在他们的家中,他们宁愿去他们的殖民地的网吧,并使用他的打印机来满足他们的短暂需求。

所有这一切都是因为这里讨论的对象是昂贵的。 从软件的角度来看,当一个对象利用大量资源来执行其操作时,它是“昂贵的”。

所以现在我们需要Singleton设计模式:

1)当应用程序在整个生命周期中不会多次使用该对象时。

2)当应用程序经常需要一个对象时,该对象本身的计算成本非常高。

单一设计模式的实施

单例设计模式表明:允许在整个应用程序中仅创建一个类的实例,并提供对它的全局访问点

所以第一部分是指“限制”建设。

从Java早期的面向对象实现开始,我们知道构造函数是在程序执行期间调用的特殊函数,它们可以是私有的。 当构造函数变为私有时,类外的任何代码都无法创建其对象。 因此,对于Singleton设计模式的实现,我们需要一个“私有构造函数”,我们将使用该构造函数在类中创建一个对象。

我们定义的第二部分讨论了为这个单个对象提供全局句柄。 我们将使用公共方法来做到这一点。