How Bad Are Singletons?
所以…
很明显,有很多关于单子,全局状态变量,以及所有这些伟大的东西的问题。我的问题是,
如果单件商品和全球商品如此糟糕,为什么它们被如此频繁地使用?
下面的例子很简单,我相信很多人都会用到。
我给你一个来自codeigner的函数,它使用psuedo-singleton函数:
(systemcodeignercommon.php第89行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * Class registry * * This function acts as a singleton. If the requested class does not * exist it is instantiated and set to a static variable. If it has * previously been instantiated the variable is returned. * * ...... */ function &load_class($class, $instantiate = TRUE) { static $objects = array(); // Does the class exist? If so, we're done... if (isset($objects[$class])) { return $objects[$class]; } ....... } |
通过将每个对象放入一个注册表中,您不能使用它们的load_类函数来创建任何对象的多个实例。当您希望将类用作数据结构时,这尤其不方便。
另外,因为所有这些类只有一个实例,所以它导致了反对全局状态的争论。这让我……
整个WordPress系统,主要运行在全局变量上。所有用于循环浏览帖子的数据都散布在不同的全球网站上。
(wp includesquery.php第2644行)
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * Setup global post data. * *.... */ function setup_postdata($post) { global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages; $id = (int) $post->ID; $authordata = get_userdata($post->post_author); .... } |
这些只是两个主要的框架示例,它们使用单例/全局作为整个系统的基础!
所以…仅仅是因为这些系统没有跟上OOP方法论吗?当有那么多人告诉你不要使用全局变量或单例变量,使你的整个系统基于上述实践时,这是没有意义的。
当然,还有关于向后兼容php4的争论。我仍然认为在php4中有一些方法可以进行oop编程,因为类仍然可用。
因为使用单例程序相对容易,而不使用单例程序则需要对应用程序的结构进行更详细的规划。不久前我问了一个关于替代品的问题,得到了有趣的答案。
人们不鼓励使用全局变量,因为它增加了错误的可能性。如果程序中的每个函数都访问相同的全局变量,那么在某个地方犯错误就容易得多,而且调试起来也困难得多。它也很难测试。
我想他们仍然经常使用,因为程序员很懒惰。我们不想把时间花在前面,让代码组织得井井有条,美观,我们只想完成这项工作。只写一个全局函数/变量/随便什么比模块化要容易得多,一旦你开始了这条路,就很难再回去重构了。也许这就是原因:他们从那条路开始,根本就没有回头。
在基于php4的应用程序(如wp或ci)中,部分原因是php4对oop结构的支持更差。
全球化和单件化也很简单:在全球化中拍打某个东西比用适当的OOP实践来构建它需要更少的思考。访问它们也比较简单,只需将代码指向名称,就可以了,而不需要从其他地方传入对象。
全局状态(全局变量、单例等)的一个负面副作用是它使单元测试变得更加困难。
PS:根据我的经验,WordPress的代码质量一般都很差。我不会用它来衡量任何事物…
可能是因为设计模式书由果夫。它变得太普遍了,人们认为它是绝对正确的。
If Singletons and Globals are So Bad,
Why are they used so often?
我认为它的要点是,单身使事情容易。至少是第一眼看到的。我对这件事没有足够的经验,不能说任何更有用的话,但是我发现下面的文章读得很好:
辛格尔顿被认为是愚蠢的(史蒂夫耶格)
在清洁的过程中,一个单体代表着将污垢隐藏在黑暗的角落,而不是清洁。
它被广泛使用,因为它能很好地隐藏问题。
对那些想打扫但又不想打扫的人来说,这是件好事。
对那些真正想清理东西的人来说,这是件坏事。
考虑依赖项注入http://martinfowler.com/articles/injection.html如果一个单身汉造成了一个问题,你就不能再藏起来了。