单身是否适合这种设计?

时间:2012-08-10 20:43:16

标签: java design-patterns singleton

我的模型已实施,我正在制作视图。

我有一个名为Helper的类,它是我的控制器的一部分。 Helper类的目的是包含"主副本"该模型。其他类将调用Helper方法来请求他们自己的模型副本(整个或特定部分)。 Helper也是唯一允许对模型进行更改的类。

我正在处理的视图包含一个名为DrawingPanel的JPanel。 DrawPanel的paint()方法被覆盖,以便在绘制自己之前从Helper中检索模型。

将Helper类作为单例实现是实现此目标的最佳方法,还是有更好/更简单/更优雅的方式来实现我的目标?

我想我也应该提前知道我的Helper作为单例的实现是否需要线程安全。 gui是在Swing中设计的。

5 个答案:

答案 0 :(得分:5)

至于资本-S“单身人士”是否合适......问自己这个......

  

第二个实例肯定会导致我的程序死亡吗?

(我的意思是“确定”和“死亡”。不只是“可能”......而不仅仅是关于哪个实例是“官方”的混淆。如果程序崩溃,内爆,打开虫洞,因为存在第二个实例,所以完全由于存在第二个实例而点燃你的狗。如果你不确定,假设“不”,直到你有合理的证据。)

如果答案为“是”,那么可能拥有使用Singleton的有效案例。如果没有,那么你就是在滥用它,而且还有一个更好的解决方案: 只是不要创建第二个实例。

使用Singleton有几个错误的原因:

  • “我希望能够使用我的对象而不会在应用程序周围传递它。”你猜怎么着?你所拥有的是一个美化的全球变量。当它隐藏在某个阶级的内容中时,它会更加邪恶,而不是让全世界都能看到它。 如果你想使用全局,那就使用一个怪异的全局。不要把它隐藏在吸气剂后面,并认为人们不会注意到。

  • “我只需要其中一个。”往上看。 你只需要一个?只有创建一个。无论你现在是否需要它,你有充分的理由强制那里只有一个吗?如果你将来想要另一个怎么办?你不仅创造了另一个人的痛苦,而且你可能以这样的方式建立你的班级,只有一个可以存在 - 并且将有很多“设计”来撤消。

  • “能说MySingleton.getInstance()很方便。”是的,直到你开始关心测试。请注意,每次调用MySingleton.getInstance()时,您都会再添加一个假设,即该对象可能是唯一的类型。如果您开始搞乱单元测试,那么您的测试将毫无用处,因为它们都依赖于该实例的行为 - 甚至是测试运行的顺序。即使是全局性也没有可测试性那么糟糕,而且有点糟糕。 (另外,请参阅上面的“......不要在应用程序周围传递它”。)

单身人士问题的解决方案通常是依赖注入。大词,但非常非常简单的前提;非框架版本基本上是“对象需要完成其工作的外部东西?将它传递给构造函数。”有一些DI容器库/包据说可以简化这个,但它只是告诉对象使用什么而不是让它去找自己的东西。所以你将你的一个实例传递给需要它的对象,它永远不必说MySingleton.任何东西 - 甚至关心该对象是否是一个单例或不。

答案 1 :(得分:3)

如果您只想拥有Helper类的一个实例,那么单例是一种强制执行该实例的方法。如果您的助手类包含任何非全局状态,则单例可能不合适。也可以有多个共享单个主模型的帮助程序实例。

但是对单身人士要谨慎,因为你的代码很快就会充满

MySingleton.getInstance()

这也难以模拟测试(参见http://jeffastorey.blogspot.com/2009/08/spring-managed-singletons-for.html)。如果您正在使用依赖注入框架,我建议将单例注入相关类(或使用类似注册表模式http://martinfowler.com/eaaCatalog/registry.html的内容来查找单例对象,这样您仍然可以将其模拟出来进行测试)。

我的回答只是一些指导,真正的答案就像许多软件问题“它取决于”。

答案 2 :(得分:1)

我会说是的,看起来你想让它成为一个单身人士。此外,如果您使用多个线程,则需要使其成为线程安全的。还有一件事,重命名,“助手”是一个可怕的名字。把它命名为它。

答案 3 :(得分:0)

我会说不,你应该避免使用提供“全局访问服务”的单身人士。

请参阅链接以及下面的内容。

http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx

  

最终发生的事情是设计中的依赖关系   隐藏在代码中,通过检查接口不可见   你的课程和方法。

答案 4 :(得分:-1)

  

将Helper类作为单例实现是最好的方法   实现这一目标,还是有更好/更简单/更优雅的方式   完成我的目标?

如果您的意图是让所有应用程序都使用一个Helper,那么就可以使用yes singleton。

  

我想我应该提前知道我的执行情况   作为单身人员的助手需要是否是线程安全的。

如果它将被多个线程访问,是的,它必须是线程安全的