用Singleton保护资源?

| 我已经读了很多关于SO的博客文章和答案,这些都指出Singleton是一个不好的设计。以前,我实现了单例CameraControl类。此类控制连接到系统的摄像机。根据以下知识: 在任何情况下都不会有一个以上的摄像头(由摄像头制造商提供的摄像头API控制所有摄像头)。 过去在多个地方同时使用相机制造商的API曾经引起过问题(例如,一个线程试图获取图像,另一个线程试图设置快门速度)。 我的课程仅提供了几种额外的方法来显示在UI中捕获的图像。将图像转发到人脸检测器,...(即它不占用大量内存)。 我选择将此课程作为单例课程是一个错误的决定吗?     
已邀请:
您迟早都可以阅读任何内容。不管什么 有人说,没有根本的理由反对使用 在适当情况下为单身人士_。就你而言,我有 严重的疑问,至少是您描述它的方式。不管 相机制造商的API(可能在C语言中) 客户端代码将把每个单独的摄像机视为 一个单独的对象,并且没有固有的独特性 相机。 单例可能合适的地方是 相机制造商使用C语言,您决定提供 一个轻量级的C ++包装器,由(专有)使用 您的相机课程。这样的轻包装纸是一种 单身人士的合法使用-世界上没有办法 在您的代码中可以包含该库的多个实例。 (不过,通常,使用Camera类地址会更容易 API,然后跳过中间包装器。)     
单例被认为是一种气味,因为: 它们在道德上等同于全局变量,因此它们的使用隐藏了代码中的依赖关系,而不是通过接口显示它们。 它们促进紧密耦合,因为您的代码取决于特定类型的特定实例。如果您希望您的用户界面有一天能与其他相机管理员一起使用怎么办? 它们使单元测试变得困难,因为它们在程序的整个生命周期内都带有状态。当状态在测试之间传递时,它可以使测试取决于状态,这是一个很大的气味。     
  我选择将此课程作为单例课程是一个错误的决定吗? 是。      在任何情况下都不会有一个以上的摄像头(由摄像头制造商提供的摄像头API控制所有摄像头)。    这并不需要通过Singleton类访问相机。      过去在多个地方同时使用相机制造商的API曾经引起过问题(例如,一个线程试图获取图像,另一个线程试图设置快门速度)。    使用Singleton类不会为您带来任何帮助,您可以摆脱非Singleton类也无法解决的问题。      我的课程仅提供了几种额外的方法来显示在UI中捕获的图像。将图像转发到人脸检测器,...(即它不占用大量内存)。    然后,无需创建类似于神的Singleton类。 此外,当您驻留在具有全局状态且无法在测试之间正确设置和拆除的Singleton类中时,您添加到Singleton类中的那些小巧的辅助功能以及它们与其他代码段的交互不易进行单元测试。 通过在应用程序组合根目录中正确使用依赖项注入,可以像对待单个对象一样管理具体对象的生存期,但该对象的各个客户端不需要知道这一点。     
我个人认为适当时使用Singletons是合理的。当然,通常可能会过度使用它们,但是我认为它们对于控制硬件资源的管理器类很有用,这就是您正在做的事情。     
是和否 不会,因为您看到的有关并发的问题是您在使用线程时无法“安全”避免的问题。迟早,不良的同步机制将再次出现,并破坏您的可爱代码。您将需要互斥体和信号量等来保护资源。 是的,因为单例是涉及线程的错误模式。检查有关单例的此页面,您将看到一些与之相关的陷阱。基本上,您是在找麻烦。 关于一般的“单子是邪恶的”,这是因为它使弄清楚它的工作方式变得更加困难,它们是全局变量的OOP版本。假设您某个地方有一个单例,并且在15个地方进行了修改,那么如何跟踪所有这些?如果您有一个“真实”对象,您将能够看到它如何在参数等中传递。单例打破了范围的概念,很容易变成混乱。     
Singleton
Monostate
模式在这方面都很有用。您的主要考虑因素(关于第二点)是防止多重访问,而Singleton和Monostate都不能阻止这一点。     
是的,使它成为Singleton是一个不好的设计。如果只需要一个Camera对象,则只需制造一个即可。 如果需要确保以非可重入方式使用相机对象,则这不是相机对象的责任,而是线程模型的责任。这是一项单独的工作。     

要回复问题请先登录注册