需要帮助避免使用Singleton

时间:2011-12-21 19:47:10

标签: c# oop design-patterns singleton

我不是单身人士的仇敌,但我知道他们受到了虐待,因此我想学会在不需要的时候避免使用它们。

我正在开发一个跨平台的应用程序(Windows XP / Vista / 7,Windows Mobile 6.x,Windows CE5,Windows CE6)。作为流程的一部分,我将代码重新分解为单独的项目,以减少代码重复,从而有机会解决初始系统的错误。

正在分离的应用程序的一个这样的部分非常简单,它是一个概要文件管理器。该项目负责存储配置文件。它有一个Profile类,其中包含应用程序所有部分使用的一些配置数据。它有一个ProfileManager类,其中包含ProfilesProfileManager将读取/保存Profiles作为硬盘上的单独XML文件,并允许应用程序检索并设置“活动”Profile。简单。

在第一个内部构建中,GUI是反模式SmartGUI。这是一个没有MVC / MVP的WinForms实现,因为我们希望它能够更快地工作而不是精心设计。这导致ProfileManager成为单身人士。这在应用程序的任何地方都是如此,GUI可以访问活动的Profile

这意味着我可以根据需要去ProfileManager.Instance.ActiveProfile检索系统不同部分的配置。每个GUI也可以对配置文件进行更改,因此每个GUI都有一个保存按钮,因此他们都可以访问ProfileManager.Instance.SaveActiveProfile()方法。

我认为在这里使用单身人物并没有错,因为我认为它没有任何错误,但我知道单身人士并不理想。 是否有更好的方法来处理它?<​​/ strong>是否应将ProfileManager的实例传递到每个Controller / Presenter?创建ProfileManager时,是否应创建其他核心组件,并在更改配置文件时注册事件。这个例子非常简单,可能是许多系统中的一个常见功能,所以认为这是学习如何避免单身人士的好地方。

P.S。我不得不针对Compact Framework 3.5构建应用程序,它确实限制了很多可以使用的普通.Net Framework类。

3 个答案:

答案 0 :(得分:8)

单身人士受到诽谤的原因之一是他们经常充当全球,共享,有时可变的州的容器。当您的应用程序确实需要访问全局共享状态时,单身人士是一个很好的抽象:您需要访问麦克风或音频播放的移动应用程序需要协调它,例如,因为只有一组扬声器。

对于您的应用程序,您有一个“活动”配置文件,应用程序的不同部分需要能够修改。我认为你需要决定用户的个人资料是否真正适合这种抽象。鉴于配置文件的表现形式是磁盘上的单个XML文件,我认为单独使用它是好的。

我认为您应该使用依赖注入或工厂模式来获取概要文件管理器。您只需要为需要使用配置文件的类来编写单元测试,以了解对此的需求;您希望能够在运行时传递以编程方式创建的配置文件,否则您的代码将与磁盘上的某些XML文件具有紧密耦合的依赖关系。

答案 1 :(得分:5)

要考虑的一件事是为您的ProfileManager创建一个接口,并将其实例传递给使用它的每个视图(或任何视图)的构造函数。这样,您可以轻松地为每个线程/用户/等提供单例或实例,或者具有转到数据库/ Web服务/等的实现。

另一个选择是让使用ProfileManager的所有东西都调用工厂而不是直接访问它。然后该工厂可以返回一个实例,它也可以是单例或不是(转到数据库或文件或Web服务等等),大多数代码都不需要知道。

不回答你的直接问题,但确实会使未来的变化影响接近于零。

答案 2 :(得分:2)

如果“单身人士”基本上用于取代“全球”变量,那么他们真的很糟糕。在这种情况下,如果这是它的用途,它不一定是Singleton。

在您描述的情况下,它很好,实际上是理想的,以便您的应用程序可以确保配置文件管理器可供所有需要它的人使用,并且应用程序的其他任何部分都无法实例化额外的应用程序与现有的冲突。这样可以减少任何地方丑陋的额外参数/字段,您尝试传递一个实例,然后保持对它的额外不必要的引用。只要它被强制进入一个且只有一个实例化,我认为它没有任何问题。

Singleton旨在避免多个实例化和单点“入口”。如果这就是你想要的,那就是你要走的路。只要确保它有详细记录。