2

我有很多用于访问数据库的管理器类。我需要创建一个管理器的实例才能访问它的方法。

由于我个人更喜欢静态类,因此我想知道您对这种方法的看法:

public static class Managers
{
    public static SomeManager Manager
    {
         get { return new SomeManager(); }
    }
}

var stuff = Managers.SomeManager.DoStuff();

有什么缺点吗?

4

4 回答 4

6

最大的缺点是对不熟悉您的代码的人来说缺乏清晰度:对我来说,像这样的调用

Managers.SomeManager.DoStuff();

意味着SomeManager以一种或另一种方式固定的访问,而不是

new SomeManager().DoStuff();

这明确告诉我这SomeManager是按需创建的。

SomeManager属性转换为具有适当名称的方法,例如MakeSomeManager(),将恢复可读性:

Managers.MakeSomeManager().DoStuff();

你可能想做这样的事情来隐藏实例化的过程SomeManager,它的构造函数可能需要一些你不愿意携带的参数。

于 2013-09-12T12:56:39.270 回答
4

这是单例模式的糟糕实现,因为每次调用属性时都会创建一个新实例。

这会更好:

public static class Managers
{
    private static SomeManager someManagerInstance;

    public static SomeManager Manager
    {
         get
         {
             if (someManagerInstance == null)
             {
                 someManagerInstance = new SomeManager();
             }
             return someManagerInstance;
         }
    }
}

当然,除非每次都需要一个新实例?在这种情况下,我会将创建包装在一个方法中,而不是一个属性中:

public static class Managers
{
    public static SomeManager GetNewManager()
    {
         return new SomeManager();
    }
}
于 2013-09-12T12:55:45.250 回答
2

使用单例模式。如果您使用的是 .NET 4 或更高版本,那么最整洁(和“最懒”的版本)是:

public sealed class SomeManager
{
    private static readonly Lazy<SomeManager> lazy = 
        new Lazy<SomeManager>(() => new SomeManager());

    public static SomeManager Instance { get { return lazy.Value; } }

    private SomeManager()
    {
    }
}

然后通过以下方式访问它:

var stuff = SomeManager.Instance.DoStuff();

实现一个线程安全的单例有很多陷阱,所以你应该看看这里的一些技巧和例子。

于 2013-09-12T13:13:11.703 回答
0

您可以改用单例,因为像这样使用静态类和方法是不好的做法。例如,尝试为您的实现编写一些单元测试,否则......

1)像这样创建单例类

    public static class Singleton<T>
    where T : class, new()
{
    /// <summary>
    /// The syncRoot.
    /// </summary>
    private static readonly object syncRoot = new object();

    /// <summary>
    /// The instance.
    /// </summary>
    private static volatile T instance;

    /// <summary>
    /// Gets the instance.
    /// </summary>
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new T();
                    }
                }
            }

            return instance;
        }
    }
}

2)像这样创建你的类

public class YourClass
{
    /// <summary>
    ///     Singleton instance of 
    /// </summary>
    public static YourClass Instance
    {
        get { return Singleton<YourClass>.Instance; }
    }
...methods etc...
}

3)从代码YourClass.Instance.SomeMethodCall()中调用你的单例;

于 2013-09-12T13:01:54.280 回答