我应该使用单例硬件管理吗?

Should I use a singleton for hardware management ?

本文关键字:管理 硬件 单例 我应该      更新时间:2023-10-16

我是OO设计的新手,我想知道Singleton设计模式的使用。我读了一些关于为什么单例不好的文章,但仍然不知道我是否需要一个。我想尽量避免。

在我的情况下,我使用海洋光学光谱仪,可以通过他们的API在c++中进行控制和咨询。

我已经把管理光谱仪的所有代码(发现它们,设置或获取参数,检索数据)放在单个类SpectrometerProxy中。

我想知道这个类是否应该是单例的。我觉得可能有几个理由可以证明这一点:

  • 管理硬件

  • 无论光谱仪的数量是多少,它们都是通过这个类控制和咨询的

  • 有一个特定的程序必须按照精确的顺序完成,而且只有一次(打开光谱仪,检查一些变量,当程序停止时关闭光谱仪)

那么,我不知道是否有更好的方法来实现这个类,而不是使它成为一个单例。我想到的另一个解决方案是保持它作为一个正常的类,但防止复制(通过声明复制构造函数和赋值操作符私有),只是传递一个指针到需要它的类:它不会阻止多个SpectrometerProxy的创建,我想避免这种情况。

我也想过把它全部变成静态的,但是这样的话,它将依赖于客户端代码以正确的顺序调用正确的静态成员函数(并且不要忘记正确关闭与光谱仪的连接),因此将容易出错,并且与RAII原则相反。

那么,对于这个问题,单例是一种可能的正确的设计方法吗?或者我应该排除它并寻找其他方法?

这主要是一个宗教主题:使用或不使用单例。根据我使用硬件的经验(10年以上),我宁愿不使用它们。首先,正如墨菲定律所说,明天你需要使用不止一台光谱仪。第二:最好是创建一个虚拟抽象接口,其中包含与硬件交互所需的方法,从它继承并编写实际处理硬件的代码。这种方式是有用的,当你没有访问硬件,但你需要调试你的应用程序。在这种情况下,你只是子类化的接口和模拟函数(或更好的函数,读取实际数据从以前记录的文件与数据,从硬件获得),但你的程序的其余部分保持不变。

我认为你应该问自己的问题是,为什么你需要一个单例类,而不是你怀疑在任何地方你只会有一个光谱仪(例如由于成本),在这种情况下,它更巧合的是一个单例,而不是任何软件设计的原因。设计模式:何时使用单例中介绍了为什么需要单例?而关于单身的消极方面,请参阅《单身有什么不好?》就我个人而言,我不太喜欢单例模式,除非从软件的角度来看,情况确实需要它,否则任何其他情况都可能导致未来的代码重构。

除了单例决策之外,我认为用一个类来发现设备和控制单个设备是一个坏主意——你在没有明显原因的情况下将不同的功能放入同一个类中。

在不了解更多的情况下很难说,但一般来说,将功能分成单独的类可能更有意义:

  • HwLookup -执行设备发现等。这可能是一个单例,但我不确定我会这样做-我没有看到任何特别的理由使它成为单例,但它可能是有意义的。它返回
  • 的单个实例
  • SpectrometerProxy(或仅Spectrometer),代表单个设备,可用于设置/获取参数,检索测量结果等)

取决于它做了多少东西,我甚至不确定我是否会把HwLookup设计成一个类:它可以是一个函数(例如,如果它所做的只是返回一个光谱仪代理列表)。在c++代码中,没有必要把所有东西都放到类中。