谁需要PHP中的单例?
请注意,几乎所有对单例的反对都来自技术角度-但它们的范围也非常有限。特别是对于PHP。首先,我将列出使用单例的一些原因,然后分析对单例使用的反对。首先,需要他们的人:
-编码大型框架/代码库(将在许多不同的环境中使用)的人们将不得不使用以前存在的不同框架/代码库,必须实现来自客户端/老板的许多不同,变化甚至是异想天开的请求/管理/部门负责人。
看到,单例模式是自我包容的。完成后,单例类对于包含在其中的任何代码都是严格的,并且其行为与您创建其方法和变量的方式完全相同。在给定的请求中,它始终是同一对象。由于不能两次将其创建为两个不同的对象,因此您知道代码中任何给定点的单例对象-即使将单例插入到两个,三个不同的旧的甚至是意大利面条式的代码库中。因此,就开发目的而言,它使工作变得更容易-即使在该项目中工作的人很多,当您看到某个给定代码库中的某个点在某个点中初始化了一个单例时,您也知道它是什么,它做什么,如何做。以及它所处的状态。如果它是传统类,则需要跟踪该对象最初在何处创建,直到代码中的这一点为止,在其中调用了哪些方法及其特定状态。但是,在此放置一个单例,如果您在编码时放弃了适当的调试和信息方法并跟踪到该单例,则您确切地知道它是什么。因此,这使得必须使用不同代码库的人变得更容易,并且有必要集成以前用不同的方法完成的代码或由您没有接触过的人完成的代码。(也就是说,vendor-project-company-无论什么都没有,什么都不支持)。对于必须使用不同代码库的人们来说,它变得更容易,并且有必要集成以前用不同的哲学完成的代码或由您没有接触过的人们完成的代码。(也就是说,vendor-project-company-无论什么都没有,什么都不支持)。对于必须使用不同代码库的人们来说,它变得更容易,并且有必要集成以前用不同的哲学完成的代码或由您没有接触过的人们完成的代码。(也就是说,vendor-project-company-无论什么都没有,什么都不支持)。
-需要使用第三方API,服务和网站的人员。
如果您仔细观察,这与先前的情况并没有太大不同-第三方API,服务,网站就像外部不受控制的独立代码库。什么都可能发生。因此,使用单例会话/用户类,您可以管理来自第三方提供商(如OpenID,Facebook,Twitter等)的任何类型的会话/授权实施-并且您可以从SAME单例对象同时完成所有这些操作-在任何状态下,无论插入哪种代码,都可以在已知状态下轻松访问它。您甚至可以在自己的网站/应用程序中为SAME用户创建到多个不同的第三方API /服务的多个会话,并执行与它们相关的任何操作。
当然,通过使用正常的类和对象,所有这些也可以与传统方法配合使用-这里的问题是,单例更加整齐,整洁,因此,与此类情况下的传统类/对象用法相比,这种方法易于管理/可测试。
-需要快速发展的人
单例的类全局行为使使用带有可构建单例集合的框架构建任何类型的代码变得更加容易,因为一旦构建好单例类,就可以轻松地使用已建立,成熟和设置的方法,并且可以随时随地以一致的方式使用。使您的课程成熟需要一些时间,但是在那之后,它们是坚如磐石,一致且有用的。您可以在一个单例中拥有任意数量的方法来完成您想要的任何事情,尽管这可能会增加对象的内存占用量,但它可以节省更多的时间来快速开发-一种在给定实例中不使用的方法一个应用程序可以用在另一个集成的应用程序中,而您只需通过一些修改即可获得客户/老板/项目经理要求的一项新功能。
你明白了。现在,让我们继续对单身人士的反对,以及反对有用的东西的邪恶斗争:
-最主要的异议是,这会使测试更加困难。
实际上,即使在采取适当的预防措施并将调试例程编码为单例代码的情况下可以轻松缓解该问题,并且意识到您将要调试单例代码的情况下,它确实在一定程度上可以做到。但是请注意,这与现有的任何其他编码原理/方法/模式都没有太大不同-只是,单例是相对较新的并且并不广泛,因此当前的测试方法最终与它们不兼容。但这在编程语言的任何方面都没有什么不同-不同的样式需要不同的方法。
这一反对意见的一个观点是,它忽略了以下事实:开发的应用程序不是用于“测试”的原因,并且测试不是进入应用程序开发的唯一阶段/过程。开发了用于生产的应用程序。正如我在“谁需要单例”一节中所解释的那样,单例可以使代码必须与之配合使用并在许多不同的代码库/应用程序/第三方服务中使用,从而减少了很多交易。在测试中可能浪费的时间,是在开发和部署中获得的时间。在第三方身份验证/应用程序/集成的时代,这特别有用-Facebook,Twitter,OpenID,还有更多,而且谁知道下一步是什么。
尽管这是可以理解的,但程序员的职业取决于他们在不同情况下的工作。对于在相对较大的公司中工作的人员,这些部门的定义部门以舒适的方式管理不同的,定义的软件/应用程序,而没有即将削减预算/裁员的厄运,并且随之而来的是需要做很多事情,其中包含很多不同的东西一种便宜/快速/可靠的方式,单身人士似乎没有必要。甚至可能妨碍了他们已经拥有的东西。
但是对于那些需要在“敏捷”开发的肮脏战work中工作,不得不执行来自其客户/经理/项目的许多不同请求(有时是不合理的)的人来说,由于前面解释的原因,单例是一种节省的选择。
-另一个反对意见是它的内存占用量更高
因为对于来自每个客户端的每个请求都会存在一个新的单例,所以对于PHP可能是一个反对。如果单例构造和使用不正确,则在任何给定时间点,如果应用程序为许多用户提供服务,则应用程序的内存占用量可能会更高。
但是,这对于您在编码事物时可以采用的任何一种方法都是有效的。应该问的问题是,这些单例所持有和处理的方法,数据是否不必要?因为,如果在应用程序获取的许多请求中它们都是必需的,那么即使您不使用单例,那些方法和数据也将通过代码以某种形式存在于您的应用程序中。因此,当您将传统的类对象1/3初始化为代码处理并将其破坏为3/4时,这将成为您要节省多少内存的问题。
瞧,用这种方式说来,这个问题就变得无关紧要了-不管有没有使用单例,都不应有不必要的方法,无论如何代码都保存在代码中的对象中。因此,对单例的反对变得非常有趣,因为它假设将有不必要的方法,即从您使用的类创建的对象中的数据。
-一些无效的异议,例如“使维护多个数据库连接变得不可能/困难”
我什至无法理解这个异议,当所有人都需要维护多个数据库连接,多个数据库选择,多个数据库查询,给定单例中的多个结果集时,只要将它们保留在单例中的变量/数组中,只要他们是必要的。这可以像将它们保存在数组中一样简单,尽管您可以发明任何想要使用的方法来实现。但是,让我们研究最简单的情况,在给定的单例中使用变量和数组:
假设以下内容位于给定的数据库单例中:
$ this- > connections = array(); (错误的语法,我只是这样输入以便给您显示图片-变量的正确声明是public $ connections = array();它的用法自然是$ this-> connections ['connectionkey'])
您可以通过这种方式在阵列中的任何给定时间建立并保留多个连接。对于查询,结果集等也是如此。
$ this-> query(QUERYSTRING,'queryname',$ this-> connections ['particulrconnection']);
可以只查询具有选定连接的选定数据库,并将其存储在您的
$ this- >结果
键为“ queryname”的数组。当然,您需要为此编写查询方法-这很简单。
这使您可以维护几乎无限数量(当然,资源限制所允许的最大数量)的不同数据库连接和结果集,所需数量不限。它们可用于实例化此单例类的任何给定代码库中任何给定点中的任何代码段。
当然,您自然需要释放结果集和不需要的连接-但这不用说,并且它不单例或任何其他编码方法/样式/概念。
此时,您将看到如何在同一单例中维护与第三方应用程序或服务的多个连接/状态。没什么不同。
长话短说,最后,单例模式只是用于编程的另一种方法/样式/理念,当以正确的方式在正确的位置使用它们时,它们与任何其他模式一样有用。这没有什么不同。
您会注意到,在抨击单例的大多数文章中,您还将看到对“全局变量”的引用是“邪恶的”。
让我们面对现实-任何未正确使用,滥用,误用的东西都是邪恶的。那不限于任何语言,任何编码概念,任何方法。每当您看到有人发布诸如“ X是邪恶的”之类的笼统声明时,就不要去看那篇文章。很有可能这是有限的观点的产物-即使观点是多年特定经验的结果-通常最终是由于以给定的风格/方法工作过多而导致的-典型的知识保守主义。
可以举出无数的例子,从“全局变量是邪恶的”到“ iframe是邪恶的”。大约在10年前,甚至提议在任何给定的应用程序中使用iframe都是异端。然后是Facebook,随处可见iframe,看看发生了什么-iframe不再那么邪恶了。
仍然有些人顽固地坚持自己是“邪恶的”-有时也是出于充分的理由-但是,正如您所看到的,有一种需求,iframe可以满足这种需求并且运作良好,因此整个世界都在前进。
程序员/编码器/软件工程师的首要资产是自由,开放和灵活的思想。