一种应用程序设置管理器的单例模式替代方案

4

我已经阅读了有关单例在代码中引起问题的所有原因,但是在以下情况下我找不到替代方法。

我有一个Java Swing应用程序。用户可以通过GUI设置影响应用程序的显示和功能的设置,并且这些设置存储在XML配置文件中并进行检索。当应用程序加载时,将构建一个SettingsManager对象。在构造函数中,设置管理器解析XML配置文件并将所有设置本地存储以进行快速访问(我将其称为缓存)。当应用程序中的设置更改时,该设置将立即写入文件,但同时也会更新缓存。

问题

如果创建多个设置管理器实例,则在一个实例中更改设置时,其他实例的缓存将变得陈旧。如果不使用单例,则修复此问题的一种可能方法是不使用缓存,而只需始终从文件中检索设置。这不是一个可怕的想法,但它并不理想。如果我这样做,我认为我必须付出额外的努力使其线程安全。

为什么单例有所帮助

如果SettingsManager是单例,那么只有一个缓存,因此它永远不会过时。然而,我已经看到这不是一个好主意,因为现在它本质上是一个全局变量,而不需要访问设置的类现在可以访问它们。从我所阅读的内容来看,还有许多其他问题。

因此,是否有其他方法来设计这个问题,而不使用单例来解决问题呢?


需要访问设置的类应该已经注入了它们。 - dantuch
你可以使用静态全局变量...或者有一种管理类并传递对象实例。你也可以实现某种引用计数方案并将此类限制为一个实例。 - peacemaker
您可以使用依赖注入库来获取类的单个实例,而无需实现Singleton模式。 - Panagiotis Kanavos
单例模式的创建是为了解决静态全局变量所带来的问题。 - Panagiotis Kanavos
在这里,您可以阅读有关单例和依赖注入的内容:http://www.androidsx.com/cant-test-that-singleton-try-dependency-injection/ 和:https://dev59.com/5XVC5IYBdhLWcg3wlyIo - dantuch
2个回答

0

您可以将SettingsManager作为单例模式在一个类内部进行管理(这个类显然不会是单例),并且只将该类实例注入到需要它的类中。使用句柄-体(也称桥接)会很好。

这样做可以兼顾两者:

  • SettingsManager仅被实例化一次,因此其缓存也不会过时。
  • 只有需要它的对象才能访问它。

显然,这个句柄-体类(或任何其他解决方案)可以在任何地方实例化,从而规避了依赖注入。因此,我不确定是否存在完美的解决方案,但这可以让您更接近目标。


0
让我跟进Brady的回答并建议将“handle-body”类上的方法声明为protected。这将限制其可用性。另一种技术是将该类放在包含名称“internal”的包中(例如com.mycorp.abc.internal)。这可能不会限制访问,但确实向其他开发人员发送了一个明确的信息,即该类/方法真的不应该被使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接