如何传递全局值(singleton vs. ???)

时间:2009-09-17 20:52:56

标签: singleton state global

我继承了一个项目,该项目在配置文件,注册表和数据库中存储各种参数。无论谁需要其中一个参数,只需直接从商店读取(在某些情况下写入)。这当然是愚蠢的,所以我的第一个想法是重构现有的代码,以便客户端不知道参数的存储位置。我创建了一个经典的AppSettings类,它具有每个参数的属性。由于商店必须具有全局范围,因此我制作了一个线程安全的单例。该类不会将参数值存储在字段中,而是通过在实际存储中读取和写入它们来充当访问点,无论是配置文件,注册表还是数据库。这些天很难避免所有关于单身人士和全球国家危险的讨论。我稍后会仔细研究依赖注入和Spring等,但是现在,我只有几个问题。

  1. 您可以在我的解决方案中看到除可测性之外的哪类问题?
  2. 什么是轻量级替代品?为每个使用参数的对象创建工厂不是一个选项(工作量太大)。
  3. 在我有机会进行更重的重构之前,不会使用单身作为可接受的妥协吗?
  4. 如果我的单例类中的属性只有getter,那会没关系吗?
  5. 我可以预期某些参数的商店将来会发生变化(例如从注册表到数据库),所以这是我将商店隐藏在单件类后面的动机。

3 个答案:

答案 0 :(得分:2)

这是一个非答案,但我强烈推荐单身人士的c2wiki页面作为参考http://c2.com/cgi/wiki?search=Singleton

还有页面http://c2.com/cgi/wiki?GlobalVariablesAreBad

我认为一般判决是全球国家在你系统的不同部分之间建立耦合,必须仔细考虑和设计。问题是,所有这些设置是否真正全球化并且需要系统的不同部分?如果没有,那么有没有办法将它们分成更小的部分,这些部分可以存在于较低访问级别的不同模块中?

如果这是一个小项目,我不会太担心它,但是在那些关于全球州和单身人士的c2wiki页面上有很多智慧对于大型项目来说是一种痛苦。

答案 1 :(得分:0)

我会质疑这样的假设,即由于配置数据是全局的,因此您需要一个全局单例来访问它,特别是对于读取。考虑创建一个AppSettings类,可以根据需要调用它来读取配置设置。

如果需要以线程安全的方式编写,可以创建AppSettings类的静态(或单例)私有成员来控制写入。因此,任何AppSettings实例都可以编写,但“全局”访问实际上仅限于AppSettings类。

答案 2 :(得分:0)

谢谢,伙计们。我认为这是一个中型项目(约200KLOC),它是C#。问题是该项目历史悠久且困难,许多程序员都在研究它。尽管我想要正确地学习依赖注入(正如我理解并订阅这个概念),但截止日期快速结束,所以现在不是时候了。在查看我当前的单例类之后,我决定将其拆分为两个实例类。一些参数全部使用,但有些只在一个程序集中使用。和Doug说的一样,我可以通过实例类轻松实现线程安全。

对于各种依赖注入框架,问题是存在太多问题。我简要地看了一下Spring和Unity。我希望我能找到差异的摘要。

再次感谢!