3 回答
TA贡献1804条经验 获得超7个赞
是的,单身人士很糟糕。它们很糟糕,因为它们为你所做的只是结合了两个属性,每个属性在95%的时间都是坏的。(这意味着平均而言,单身人士在99.75%的时间里表现不佳;))
由GoF定义的单例是一种数据结构:
授予对象的全局访问权限
强制只能存在一个对象实例。
第一个通常被认为是一件坏事。我们不喜欢全局变量。第二个是更微妙,但一般来说,实际上没有任何情况下这是一个合理的强制执行限制。
有时,只有一个对象实例才有意义。在这种情况下,您选择只创建一个。您不需要单例来强制执行它。
通常情况下,即使只有一个实例“有意义”,事实证明它根本没有意义。迟早,你需要不止一个记录器。或者多个数据库。或者您将不得不为每个单元测试重新创建资源,这意味着我们必须能够随意创建它们。在我们理解后果之前,它过早地从我们的代码中消除了灵活性。
单例隐藏依赖关系并增加耦合(每个类都可能依赖于单例,这意味着除非我们还重用所有单例,否则该类不能在其他项目中重用),并且因为这些依赖关系不是立即可见的(作为函数/构造函数参数) ),我们没有注意到它们,通常在我们创建它们时不会考虑它们。只需拉入一个单例就可以了,它几乎就像一个局部变量一样,所以我们倾向于在它们存在时使用它们很多。这使他们几乎不可能再次删除。你最终,也许不是意大利面条代码,而是意大利面依赖图。迟早,你失控的依赖关系将意味着单身人士开始依赖彼此,然后在尝试初始化时获得循环依赖关系。
他们使单元测试非常困难。(如何测试在单个对象上调用函数的函数?我们不希望运行实际的单例代码,但是我们如何防止这种情况?
是的,单身人士很糟糕。
有时,你真的想要全球化。然后使用全局而不是单身。
有时,非常非常非常罕见,你可能有一种情况,创建一个类的多实例是一个错误,它可以没有导致错误进行。(关于我能想到的唯一一个案例,即使这是设计的,如果你代表一些硬件设备。你只有一个GPU,所以如果你要将它映射到代码中的一个对象,它会理解只有一个实例可以存在)。但是,如果您发现自己处于这种情况(并且再次强调,多个实例导致严重错误的情况,而不仅仅是“我无法想到多个实例的任何用例”),那么执行该约束,但不要使对象全局可见。
每个这两个属性可以是有用的,在极少数情况下。但我想不出一个案例,他们的组合将是一件好事。
不幸的是,很多人都认为“Singletons是符合OOP标准的全局变种”。不,他们不是。除了介绍其他一些完全不相关的问题之外,他们仍然遇到与全局问题相同的问题。绝对没有理由比普通的全球更喜欢单身人士。
TA贡献1847条经验 获得超7个赞
软件开发人员似乎分成两个阵营,这取决于他们是赞成理想主义的编码风格还是实用的编码风格:
理想主义:永远不要使用单身模式。
务实:避免单身模式。
就个人而言,我赞成务实的做法。有时违反规则是有道理的,但前提是你真正了解自己在做什么,并愿意接受相关的风险。如果您对以下关于特定用例的问题回答“是”,则单例模式可以产生一些实际好处。
单身是你的应用程序的外部吗?数据库,排队服务和ESB都是单例模式的完全有效的宏示例。
KISS:你的整个应用仅限于2-3个内部单身人士吗?
DRY:那些单身人士本身是否具有全球性,因此不得不在你的应用程序中几乎每个对象中引用参考文献?(例如,记录器或组件介体)?
您的单身人士是否仅依赖于彼此和/或操作环境?
您是否确保了每个单例的正确启动和关闭顺序,包括内存管理注意事项?例如,“Grand Central”样式的线程池可能需要在main()中具有实例Run()和Shutdown()方法,以便保证任务仅在它们操作的对象处于有效状态时运行。
- 3 回答
- 0 关注
- 659 浏览
添加回答
举报