单例数据访问层

3
在我们的工作数据访问层中,我们有这样一个标准实现,即通过单例公共属性访问类,其代码大致如下:
public static CustomerController Instance
        {
            get 
            {
                lock(singletonLock)
                {
                    if( _instance == null )
                    {
                        _instance = new CustomerController();  
                    }
                    return _instance;
                }
            }
        }

现在,我明白代码在做什么,但我想知道为什么要这样做,而不是每次使用时创建类的实例?

3个回答

2

编辑:哦,糟糕,我没注意到“数据访问层”的部分。但我也有一个例子:如果您的多线程应用程序通过单例类传递所有数据库调用,则只有一个线程会访问数据库,避免竞争条件。

如果您在多线程应用程序中使用日志记录机制,用于输出所有异常并仅在其中写入信息(特别是用于服务或始终运行的应用程序,在发生事件时打印状态),则会遇到文件锁定问题。我使用单例记录器类,因此只有一个线程才能访问记录器,其余线程将等待直到记录器可用于在文本文件中写入它们的行。

使用单例类有很多很酷的理由,但在多线程应用程序中遇到文件访问问题之前,我和你一样不知道它们是用来做什么的。


我能理解在这种情况下单例的必要性,但如果你正在访问数据库,是否真的需要一个类的单例实例? - lomaxx
数据库有什么用?我是在谈论写入文本文件的情况,在这种情况下,您只能每次有一个线程访问文件。 - goldenratio
哦,对不起,我以为你是在问单例模式的一般用途。"数据访问层"这部分我没有理解清楚,抱歉! - goldenratio

1

你可能也希望这样做,使用双重检查锁定,可以加速访问单例。

 public static CustomerController Instance
        {
                get 
                {
                        if( _instance == null )
                        {
                           lock(singletonLock)
                           {
                                if( _instance == null )
                                {
                                        _instance = new CustomerController();  
                                }

                            }
                        }   
                        return _instance;
                }
        }

1
答案很简单:您希望每次使用时都获得相同的对象。
这样做可以让您既享有全局变量的优点(即只有一个实例),又享有类对象的优点(其中包括在第一次需要时进行不可见初始化)。

为什么将其作为全局变量是一件好事呢?看起来它只是一个单例,为了让它成为一个单例而已。 - lomaxx
有时候拥有一个 Singleton 并不会为您带来任何好处。如果您的应用程序是单线程的,那么不需要将其设置为 Singleton。然而,如果您从一开始就将其设置为 Singleton,则不会产生任何负面影响,而且如果您将来将其变成多线程,则无需进行重构。 - goldenratio
@lomaxx:你不想把它作为全局变量。首先,这会污染命名空间。其次,需要有东西来初始化它。单例模式可以解决这两个问题。 - staticsan
@ goldenratio:这与是否线程有关无关。单例意味着您可以在任何地方请求它,代码将始终获得相同的对象。代码不必在各个地方传递资源。如果不需要,它就不会请求它。 - staticsan

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