0

我的模型已经实现,我正在研究一个视图。

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

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

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

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

4

5 回答 5

5

至于大写-S“Singleton”是否合适……问问自己这个……

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

(我的意思是“确定”和“死亡”。不仅仅是“可能”......而且不仅仅是关于哪个实例是“官方”实例的一些混淆。如果程序崩溃,内爆,打开虫洞,放火你的狗等完全由于第二个实例的存在,答案是“是”。如果你不确定,假设“否”,直到你有充分的证据。)

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

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

  • “我希望能够使用我的对象,而无需在应用程序中传递它。” 你猜怎么了?你所拥有的是一个美化的全局变量。当它藏在某个阶级的内心深处时,它甚至比它坐在外面让全世界都看到更邪恶。 如果你想使用一个全局,那么使用一个该死的全局。 不要将它隐藏在吸气剂后面,并认为人们不会注意到。

  • “我只需要其中一个。” 往上看。 你只需要一个?只创建一个。 不管你现在是否需要它,你有充分的理由强迫它永远存在吗?如果你将来想要另一个怎么办?您不仅让创建另一个类变得很痛苦,而且您可能已经以一种只能存在一个的方式构建您的类——并且将有很多“设计”要撤消。

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

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

于 2012-08-10T22:33:37.633 回答
3

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

不过要小心单例,因为你的代码很快就会充满

MySingleton.getInstance()

这也很难模拟进行测试(请参阅http://jeffstorey.blogspot.com/2009/08/spring-managed-singletons-for.html)。如果您使用的是依赖注入框架,我建议将单例注入相关类(或使用注册表模式http://martinfowler.com/eaaCatalog/registry.html之类的东西来查找单例对象,以便您仍然可以模拟用于测试)。

我在这里的回答只是一些指导,真正的答案就像很多软件问题是“视情况而定”。

于 2012-08-10T20:55:45.940 回答
1

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

于 2012-08-10T20:57:04.993 回答
0

我会说不,您应该避免使用提供“对服务的全局访问”的单例。

请参阅下面的链接和除外。

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

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

于 2012-08-10T20:57:00.000 回答
-1

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

如果您的意图是让Helper您的所有应用程序都使用一个单一的,那么是的,单例是要走的路。

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

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

于 2012-08-10T20:55:22.260 回答