0

我继承了一个项目,该项目将各种参数存储在配置文件、注册表和数据库中。需要这些参数之一的人只需直接从存储中读取(并且在某些情况下写入)它。这当然是愚蠢的,所以我的第一个想法是重构现有代码,以便客户端不知道参数存储在哪里。我创建了一个经典的 AppSettings 类,它为每个参数都有一个属性。由于商店必须具有全局范围,因此我制作了一个线程安全的单例。该类不将参数值存储在字段中,而是通过在实际存储(无论是配置文件、注册表还是数据库)中读取和写入参数值来充当访问点。这些天来,很难避免所有关于单例和全局状态的危险的讨论。

  1. 我的解决方案除了可测试性之外,还有哪些类型的问题?
  2. 什么是轻量级的替代品?为每个使用参数的对象创建工厂不是一种选择(工作量太大)。
  3. 在我有机会进行一些更重的重构之前,使用单例是否可以作为一种可接受的折衷方案?
  4. 如果我的单例类中的属性只有吸气剂,那会好吗?

我可以预料到某些参数的存储将来会发生变化(例如,从注册表到数据库),所以这就是我将存储隐藏在单例类后面的动机。

4

3 回答 3

2

这有点无法回答,但我强烈推荐 c2wiki 的单身人士页面作为参考http://c2.com/cgi/wiki?search=Singleton

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

我认为一般的判断是,全局状态会在系统的不同部分之间产生耦合,必须非常仔细地考虑和设计。问题是,所有这些设置真的是全局的并且系统的不同部分都需要吗?如果没有,那么有没有办法将它们分成更小的部分,这些部分可以以较低的访问级别存在于不同的模块中?

如果这是一个小项目,我不会太担心,但是在那些 c2wiki 页面上有很多关于全局状态和单例对大型项目来说是痛苦的智慧。

于 2009-09-17T21:26:35.987 回答
0

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

至于各种依赖注入框架,问题是太多了。我简要介绍了 Spring 和 Unity。我希望我能找到差异的摘要。

再次感谢!

于 2009-09-18T07:00:07.167 回答
0

我会挑战这样的假设,即由于配置数据是全局的,因此您需要一个全局单例来访问它,尤其是在阅读时。考虑创建一个 AppSettings 类,可以根据需要调用它来读取您的配置设置。

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

于 2009-09-17T21:04:01.127 回答