这是一个很好的使用Singleton模式?

时间:2009-04-27 14:25:43

标签: design-patterns oop singleton

我做了很多“设计你自己的____”应用程序 我所做的是创建一个单例类来保存用户选择的所有自定义。例如:当您选择想要绿色的东西时,它会将单例中的getter / setter更新为绿色。然后当应用程序需要知道选择了什么颜色时,它会从同一个getter / setter获取信息 我以前的方式是将信息存储在UI中(只需检查从下拉列表中选择的颜色)。
在阅读了MVC之后(我仍然没有“完全”理解MVC)我现在知道这是完全错误的,这就是为什么我将它抽象为包含所有这些的单例类。

现在我想知道这是不是一个坏主意?如果是这样我该怎么做呢?

感谢。

8 个答案:

答案 0 :(得分:5)

我认为这并不是Singleton模式的用途。这是一种非常被误解的模式,人们使用它的最常见原因似乎是它很容易访问,因为它们通常是静态的。真正发生的是你有一个配置问题,你试图通过一个可以轻松访问整个应用程序的静态单例来解决。当试图控制对真正有限的资源的访问时,“正确”使用。

如果您认为对应用程序只有一个通用的“配置”可能真的没有意义。拥有几个,但也许只有一个曾经一次使用它更有意义。

CNC中 而不是使用可以静态访问的Singleton考虑使用依赖注入或控制反转。

答案 1 :(得分:3)

单身人士通过设计将实例数量限制为一个。在你的情况下,为什么你决定你必须只有一个实例?如果您想要多个配置怎么办?您的设计无法实现多个实例,每个实例代表不同的配置。

答案 2 :(得分:2)

请记住,Singleton基本上是一个全局变量,并且具有所有相同的问题。例如:

  • 每个类都可能依赖于单例(以及单例本身所依赖的任何东西)。但是,通过你传递的值,这种依赖关系并不明确,因此无法检测到它。
  • 由于您可以从程序中的任何位置写入,因此每次调用函数时都可能会更改它。所以你永远不能完全依赖它的价值。

我知道将一个对象传递给需要它的程序的每个部分是一件痛苦的事。但这最终会带来更好的设计。

  • 它会强制您减少依赖于数据对象的类数。
  • 这将使重构变得更容易,也更容易预测,因为您可以确信您的对象背后没有被更改。

答案 3 :(得分:1)

我假设你在谈论像car configurator这样的东西 - 选择油漆,引擎,轮辋和所有其他东西。

在这种情况下,我不会使用单身人士。不是因为它不起作用,而是因为它似乎在语义上是错误的。单身人士意味着只有一个州。但是您的应用程序可能有两个窗口 - 类似于两个文档。使用单例,您无法独立修改这两个文档,因为它们共享其状态。所以你看,它真的不应该是单身人士。

答案 4 :(得分:0)

我,作为一个Service Layer人(虽然我有自己的服务层愿景),建议做一些IoC并将所有自定义逻辑移动到单独的服务(AmbienceService或者其他的东西)。因此,在你的演示者中你会做(C#式伪代码):

viewModel.HeaderColor = ServiceLocator.Resolve<AmbienceService>().HeaderColor;

答案 5 :(得分:0)

我不完全确定你的问题是什么,但这就是我正在做的事情。

您的应用程序有一个UI,允许用户选择一组参数(例如,使用一组颜色下拉。其中一个是绿色。)

稍后(例如在关闭应用程序并重新启动它之后),需要再次加载所选的值。

如果这是您的具体问题,我并不认为这与单身模式本身有任何关系。我想你想要的是一个配置文件(app.config用于应用程序,web.config用于web应用程序)。 使用ConfiguratoinManager类,您可以轻松访问这些。

答案 6 :(得分:0)

您的问题的答案可能与您当前的环境有很大关系。例如,在Java中,运行时属性是通过System.getProperties等提供的.Windows有其注册表。

您是否考虑过使用上下文转换状态等解决方案?你真的需要全球物业吗?您的属性可以在运行时更改吗?您是否有多个线程可能修改相同的属性?这些都是设计中需要考虑的事情。

就个人而言,我通常只选择适合我工作环境的惯例。从您的上一个问题来看,听起来您正在使用ActionScript,是否已经存在约定?

答案 7 :(得分:0)

这不是你应该使用的模式。我认为你应该尝试一种状态模式。 Singleton适用于需要访问来自许多不同地方的有限资源的情况。

像打开和读取配置文件一样。而不是阅读相同文件的不同类,而是通过仅执行该操作的类。您需要的是当用户更改设置时,系统需要通知某些内容已被更改。

但这实际上取决于您使用的语言。据我所知,只有java有一个onNotify()方法。但我可能是错的。