我有很多用于访问数据库的管理器类。我需要创建一个管理器实例才能访问它的方法。
由于我个人更喜欢静态类,我想知道你对这种方法的看法:
public static class Managers
{
public static SomeManager Manager
{
get { return new SomeManager(); }
}
}
var stuff = Managers.SomeManager.DoStuff();
有任何缺点吗?
答案 0 :(得分:6)
最大的缺点是不熟悉你的代码的人不清楚:对我来说,这样的电话
Managers.SomeManager.DoStuff();
表示以某种方式访问SomeManager
,而不是
new SomeManager().DoStuff();
它明确告诉我SomeManager
是按需创建的。
将SomeManager
属性转换为具有适当名称的方法,例如MakeSomeManager()
,将恢复可读性:
Managers.MakeSomeManager().DoStuff();
你可能想要做这样的事情,以隐藏实例化SomeManager
的过程,其构造函数可能需要一些你不愿意随身携带的参数。
答案 1 :(得分:4)
这是singleton pattern的错误实现,因为每次调用属性时都会创建一个新实例。
这会更好:
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();
}
}
答案 2 :(得分:2)
使用Singleton模式。如果你使用的是.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();
实现一个线程安全的单例有很多陷阱,所以你应该查看this的一些提示和示例。
答案 3 :(得分: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();