2013-05-13 67 views
2

所以我比较新的OO设计,我想知道使用Singleton设计模式。我已阅读了一些关于why singletons are bad的文章,但仍无法弄清楚我是否需​​要一个。我想尽可能避免它。我应该使用单身进行硬件管理吗?

就我而言,我使用的是OceanOptics光谱仪,它可以通过C++进行控制和咨询。

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

我想知道这个班是否应该是单身人士。我觉得有可能是可以证明它有几个原因:

  • 它管理的硬件

  • 不管光谱仪的数量,他们都在控制和协商通过这个类

  • 有一个特定的程序必须按照精确的顺序进行,并且只能进行一次(打开光谱仪,检查一些变量,并在程序停止时关闭分光计)

然后,我不知道是否有更好的方法来实现这个类,而不是做一个单身人士。我想到的另一个解决方案是将它保留为普通类,但是防止复制(通过声明复制构造函数和赋值运算符为private),并将指针传递给需要它的类:它不会阻止创建多个SpectrometerProxy,我喜欢避免这种情况。

我也想过让它全部是静态的,但是它会依靠客户端代码以正确的顺序调用正确的静态成员函数(并且不会忘记正确关闭光谱仪的连接),因此会容易出错并且违背RAII原则。

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

+1

简答:“不”。较长的回答:“你为什么?” – jalf 2013-05-13 09:59:36

+0

我知道我不应该。我读过为什么单身人士不好。 “你为什么?”是我的问题。另一部分是“什么是可能的选择?”。谢谢。 – JBL 2013-05-13 10:07:51

+1

今天,你认为你想通过一个代理来控制你所有的光谱仪。明天,您可能需要多个独立代理。如果只有一个硬编码假设,那将会更困难。 – 2013-05-13 10:31:25

回答

4

它主要是一个宗教主题:使用或不使用单身。根据我使用硬件(10年以上)的经验,我愿意不要使用它们。第一:as Murphy's law明天说,你需要使用更多的光谱仪。其次:最好是用你需要与硬件交互的方法创建一个虚拟的抽象接口,从它继承并编写一个代码,实际上处理硬件。如果您无法访问硬件,但需要调试应用程序,则此方法非常有用。在这种情况下,您只需对该接口进行子类化并制作仿真函数(或更好的函数,即从以前记录的数据中读取来自硬件的实际数据),但程序的其余部分保持不变。

+1

感谢您提供虚拟抽象界面。这感觉很明显,很简单,但我没有想到它。这将是有用的,因为我并不总是可以使用光谱仪进行测试。 – JBL 2013-05-13 10:09:57

2

我认为你应该问自己的问题是为什么你需要一个单例级别,而不是你怀疑在任何位置你只有一个光谱仪(例如由于成本),在这种情况下,它更巧合地是一个单身人士比任何软件设计的原因。为什么你可能想要一个单身人士包含在On Design Patterns: When to use the Singleton?中,单身人士的消极方面包含在What is so bad about singletons?中。就个人而言,除了从软件的角度来看情况实际上需要它之外,其他任何事情都可能导致未来的代码重用,除此之外,我不是单身模式的忠实粉丝。

1

除了单身决定,我认为只有一个班级来发现设备和控制个人设备是一个坏主意 - 你没有明显的理由将不同的功能放入同一班级。

这是很难不知道多说,但在总体上可能会更有意义的功能分成不同的类别:

  • HwLookup - 进行设备发现等,这可能是一个单身,但我我不确定我会这样做 - 我没有看到有任何特别的理由让它成为单身人士,但它可能是有道理的。它返回的
  • SpectrometerProxy(或只是Spectrometer),它代表一个设备,可以用来设置/获取参数,获取测量结果等)

取决于多少东西呢,我个人情况甚至不知道我是否将HwLookup设计为一个类:它可以是一个函数(例如,如果它只是返回一个光谱仪代理列表)。没有理由把所有东西都放到C++代码中。

+0

好吧,我有点像硬件查找类的想法返回设备的“实例”,但在我的情况下,我需要调用一个函数打开所有的光谱仪,当程序关闭时,一个函数关闭所有光谱仪(它释放它们)。这两个步骤一次只能完成一次。因此,至少在硬件查找和管理中使用单例的想法会在启动和关闭时自动执行这些步骤。 – JBL 2013-05-13 10:03:31

相关问题