【问题标题】:Good example of Singleton usage单例使用的好例子
【发布时间】:2021-10-18 18:43:17
【问题描述】:

最近我阅读了很多关于 Singleton 模式的内容。就我而言,只有在没有意义的情况下才应该使用单例对象,并且需要从整个程序中访问它们。我的问题很简单,出于教育目的。 在制作 MonopolyCatan棋盘游戏 模拟器时,将 Dice(可投掷棋盘游戏骰子)创建为单例类是否正确?

【问题讨论】:

    标签: design-patterns singleton dice


    【解决方案1】:

    这里要问的问题是你从单例行为中获得了什么价值。您已将此描述为“只有在没有意义的情况下拥有多个,并且需要从整个程序中访问它们时”。细微差别在于即使拥有多个实例没有用,您也可以选择反对单例:如果没有任何实例,则允许创建多个实例可能没问题显着的缺点。

    请记住,如果您很好地实现了 Singleton,则该对象在应用程序的整个生命周期内都不会被销毁,并且您需要同步对象的创建,这样多个线程就不能创建多个实例。对于重对象或具有重依赖关系的对象,这实际上可能会导致更大的长期内存使用,因为您无法在应用程序的整个生命周期中销毁或垃圾​​收集对象。这在哪些对象可以是单例对象和哪些对象应该是单例对象之间留下了差距。这需要你的判断。

    需要考虑的一些因素:

    1. 如果创建了多个应用程序,您的应用程序是否正确?对于 DatabaseService 或 StorageService 之类的东西,答案可能是“否”,在这种情况下,Singleton 行为是绝对需要的。

    2. 如果创建多个应用程序,您的应用程序会有良好的性能吗?对于像 WebRequestService 这样的东西,拥有一个对象队列或管理请求可能会有一些额外的价值,这可能是使其成为 Singleton 的一个很好的动机。

    3. 如果您的对象必须是单例的,那么创建它的成本是否很高,或者它的创建频率是否足以想要重用该对象?在这种情况下,您必须权衡创建成本与 Singleton 的成本。想象一个 Dictionary 或 SpellChecker,即使您创建一个新的,结果也是正确的,但您希望最小化从磁盘读取字典文件的次数。有时有比 Singleton 更多的选择,such as Dagger's @Reusable scope,这会以更少的成本为您带来一些好处。

    对于你的骰子课:

    • 如果 Dice 类恰好代表创建对象时确定的一个骰子,显然它不能是 Singleton,因为那样你只能掷一次骰子,它总是会返回相同的值。 You probably don't want that.
    • 如果您的 Dice 类表示一个纯(伪)随机数生成器,它通常不必是单例:创建它可能很便宜,并且按顺序询问相同的对象可能没有优势。您可以合理地使其“可重用”或将 Dice 对象保存在池中以避免重新创建它们,但如果我正在编写代码,我认为这不太可能值得。
    • 如果您希望您的游戏是可重复的,例如在集成测试中有可预测的游戏,将 Dice 对象设置为 Singleton 可能是有意义的:在这种情况下,您可能需要单个对象以便可以调用它相同的订单并收到相同的随机种子结果。
    • 如果您要调用像 https://www.random.org 这样的随机数服务,则将对象设为 Singleton 可能很重要,以便它可以批处理、缓存和重用这些请求。

    对于“骰子”,我会使其“无范围”,每次都创建一个新实例并允许在测试中替换它。相比之下,您的 Board、Game 或 GameState 对象在整个应用程序中为 Singleton 可能是有意义的。

    【讨论】:

    • 所以一般来说 Dice 是单例的正确示例,但“不太可能值得”,对吧?
    • 除非你有我在项目符号中提到的复杂性之一,否则我认为它可以是不应该是单例。与我列出的其他例子相比,我不会称之为一个很好的例子。
    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 2013-10-17
    相关资源
    最近更新 更多