用Singleton守护资源?

时间:2011-04-12 14:46:25

标签: c++ design-patterns singleton

我已经阅读了不少博客文章和答案,指出Singleton是一个糟糕的设计。以前我实现了一个单独的CameraControl类。该类控制连接到系统的摄像机。根据以下知识:

  • 在任何情况下都不会有多台摄像机(摄像机制造商提供的摄像机API控制所有摄像机)。
  • 同时在多个地方使用相机制造商的API导致过去出现问题(例如,一个线程试图抓取图像,另一个线程试图设置快门速度)。
  • 我的课程仅提供了几种额外的方法来显示在UI中捕获的图像。将图像转发到面部检测器,...(即,它不是存储器密集型的)。

我选择让这个班级成为一个不好的决定吗?

7 个答案:

答案 0 :(得分:6)

单身人士被认为是一种气味,因为:

  • 它们是全局变量的道德等价物,因此它们的使用隐藏了代码中的依赖关系,而不是通过接口揭示它们。

  • 它们促进了紧耦合,因为您的代码依赖于特定类型的特定实例。如果您希望某天的UI能够针对不同的相机管理器进行操作,该怎么办?

  • 他们使单元测试变得困难,因为它们在程序的整个生命周期中都带有状态。当状态从测试到测试时,它可以使测试依赖于状态,这是一个非常大的气味。

答案 1 :(得分:2)

  

我选择让这个班级成为一个不好的决定吗?

  
      
  • 在任何情况下都不会有多台摄像机(摄像机制造商提供的摄像机API控制所有摄像机)。
  •   

这不需要通过Singleton类访问摄像机。

  
      
  • 同时在多个地方使用相机制造商的API导致过去出现问题(例如,一个线程试图抓取图像,另一个线程试图设置快门速度)。
  •   

使用Singleton类不会为您带来任何可以帮助您避免在非Singleton类中无法解决的问题。

  
      
  • 我的课程仅提供了几种额外的方法来显示在UI中捕获的图像。将图像转发到面部检测器,...(即,它不是存储器密集型的)。
  •   

然后就没有必要创造一个像神一样的单身人士课程。

此外,您添加到Singleton类中的那些小巧的帮助程序功能以及它们与其他代码段的交互在驻留在具有全局状态的单例类中时不能轻易地进行单元测试,该全局状态无法在测试之间正确设置和拆除。

通过在应用程序组合根中正确使用依赖项注入,可以像管理单例一样管理具体对象生存期,但该对象的各个客户端不需要知道

答案 2 :(得分:2)

您可以早晚阅读任何内容。无论如何 有人说,没有根本原因反对使用 适当情况下的单身 _。在你的情况下,我有 严重的怀疑,至少你所描述的方式。不管 相机制造商的API(可能在C中),你的 客户端代码将要将每个单独的相机视为 一个单独的对象,并没有任何不可思议的独特之处 相机。

这里的单身可能是合适的,如果是API的话 相机制造商在C,你决定提供 一个轻量级的C ++包装器,可以(专门)使用 你的相机课程。这种轻质包装纸是一种 合法使用单身人士 - 世界上没有办法让你 可以在代码中有多个库实例。 (通常,拥有Camera类地址更容易 直接使用API​​,并跳过中间包装器。)

答案 3 :(得分:1)

我个人认为在适当的时候使用单身人士是合理的。一般来说肯定会过度使用它们,但在我看来,它们对于控制硬件资源的管理器类很有用,这就是你正在做的事情。

答案 4 :(得分:1)

是和否

不,因为您看到的并发问题是在玩线程时无法“安全”避免的问题。迟早会出现错误的同步机制,并且会破坏您可爱的代码。您将需要互斥锁和信号量等来保护资源。

是的,因为单例是涉及线程的坏模式。检查this page about singletons,你会看到一些与之相关的陷阱。基本上,你是在寻找麻烦。

关于一般的“单身人士是邪恶的”,这是因为它更难弄清楚它是如何工作的,它们是全局变量的OOP版本。假设你有一个单独的地方,在15个地方被修改,你如何追踪它?如果你有一个“真正的”对象,你将能够看到它在参数等方面的传递方式。单身人士打破了范围的概念,很容易变成一团糟。

答案 5 :(得分:0)

在这方面,

SingletonMonostate模式都很有用。您的主要考虑因素(关于您的第二点)是防止多次访问,Singleton和Monostate都不会阻止这种情况。

答案 6 :(得分:0)

是的,将它变成Singleton是一个糟糕的设计。如果您只需要一个Camera对象,只需制作一个。

如果您需要确保以不可重入的方式使用相机对象,那么这不是Camera对象的责任,而是您的线程模型的责任。这是一项单独的工作。