如何重构单例类并避免再次犯同样的错误

时间:2015-04-30 08:59:50

标签: c# design-patterns singleton static-classes

我在WPF中启动了一个小应用程序,并使用Singleton类来处理所有应用程序逻辑。另外,我在那里有一些ObservableCollections绑定到View上的DataGrids。

问题:本来应该是一个小程序的功能开始增长,代码现在太难维护,重用并且代码耦合程度很高。

所以我开始将代码移到其他类中。例如,我是一个只处理文件读数的类。我已经将这个类设置为静态,因为我只运行一次这些方法(当我需要将数据导入数据库时​​),当它们完成时我不再需要那些对象而只是忘记它们存在。

现在我正在考虑对其他方法做同样的事情,比如从数据库中检索数据的方法。

我怀疑的是,这是解决问题的正确方法吗?我担心静态类的使用会像单个元素的增加一样。

1 个答案:

答案 0 :(得分:1)

有些人认为静态类是邪恶的,但这只是一种观点。当我有这些问题时,我会看一下.NET框架:它是如何在那里解决的?

有时可以将单例重构为静态类。这取决于实际情况。如果你的单例是一个继承(读取:必须继承)其他类或接口的类型,它就不能转换为静态类,因为静态类不能继承任何东西。

如果创建静态类,请尝试遵守以下规则:( .NET框架也遵守这些规则):

  • 所有静态成员必须是线程安全的。

就是这样! :)

这条规则听起来很简单,但意味着很多:

  • 所有静态成员彼此独立工作。因此,一次通话永远不会影响另一次通话的结果。
  • 不允许静态类维持(静态)状态。
  • 如果类具有静态字段,请确保它们是readonly或const。确保这些字段的内容永远不会更改。

当然可能会有一些例外。例如:静态类可以维护内部字典以缓存结果。修改此缓存必须是线程安全的。因为它是内部的东西,对于外部世界,静态类仍然遵守上述规则。

所以...简而言之:如果您的单例不是线程安全的(保持状态等),请不要将其转换为静态类。

*编辑*

使用单例通常意味着您具有包含特定类型的一个实例的静态属性。由于这是一个静态属性,它还必须遵守上述规则,这意味着该实例必须是线程安全的。

如果您的(单例)实例不是线程安全的,请重新设计您的应用程序,使其不使用此单例或静态类。让所有代码在需要时创建此类的新实例。