我一直在审查一些旧项目的代码,我在那里找到了一个单身人士。这是一个要求使用单身人士,我正在考虑一种让它看起来更简单的方法"使用时。
我发现,访问像静态类这样的方法和属性会更容易。所以我基本上使用静态方法实现了单例,以跳过使用GetInstance()
的要求。这就是我实现它的方式:
public class ExampleSingleton
{
string someRequiredValue = "This is an example.";
/// <summary>
/// Private Constructor
/// </summary>
private ExampleSingleton() { }
private static volatile ExampleSingletoninstance;
/// <summary>
/// !!! PRIVATE !!!
/// Instance Property.
/// Returns the instance of this singleton.
/// (ThreadSafe)
/// </summary>
private static ExampleSingleton Instance
{
get
{
if (instance == null)
{
lock (_lock)
{
if (instance == null)
{
instance = new ExampleSingleton();
}
}
}
return instance;
}
}
/// <summary>
/// Example field contains a value that should be
/// accessible from outside.
/// </summary>
public static string SomeRequiredField
{
get
{
// Here you do the job you would have to do "outside"
// of the class normally.
return ExampleSingleton.Instance.someRequiredValue;
}
}
// Helper for a secure thread synchronisation.
private static object _lock = new object();
}
因此,当您想要访问单例值时,您可以这样做:
// Access the values like this
string requiredField = ExampleSingleton.SomeRequiredField;
// Instead of this
string requiredField = ExampleSingleton.Instance.SomeRequiredField;
// Or even this
string requiredField = ExampleSingleton.GetInstance().SomeRequiredField;
我是否违反了单身人士模式的原则?它基本上仍然是一个单例模式,但获取实例的工作是在内部完成的。这个例子的概念可能是什么?还有其他职业选手吗?
由于
答案 0 :(得分:3)
就缺点而言,过去有两个人咬过我:
即,我认为:
ExampleSingleton.Instance.SomeRequiredField
更容易模拟,因为您需要替换/还原实例字段。关于“如何模拟静态这个或那个”的问题可能不时出现,可能是由于你发布的那个类:
一般来说,C#中的单例模式可能不是最好的主意,因为它们通常更难模拟,除非你将构造函数设为public或使用ioc容器,但是如果你需要一个,那么实例getter可能更容易测试。
第二点更多的是代码的增量维护成本。基本上要“添加到类”中,您必须更改两个代码点:
class ExampleSingleton
{
... existing code ...
public static int ComputeComplicatedMethod()
{
return ComputeComplicatedMethodImplementation();
}
private int ComputeComplicatedMethodImplementation()
{
// really complex code.
}
}
因此,您基本上为每个新字段添加了一个额外的抽象层,而对于一个get实例字段只需添加一次。或者你有一个使用内部静态单例的静态方法,如下所示:
class ExampleSingleton
{
... existing code ...
public static int ComputeComplicatedMethod()
{
// use ExampleSingletonInstance here
}
}
这真的没有比仅使用静态方法的静态类更好的了。一个更好的问题是为什么Singleton模式不仅仅用静态类实现?这可能会更好地解释:http://www.dotnetperls.com/singleton-static
答案 1 :(得分:1)
我认为你必须选择代码最少的解决方案(但看起来人们喜欢写一堆无用的代码,所以你可能很难解释你的意思。)
使用静态访问属性,例如在示例中保存一个单词:
string requiredField = ExampleSingleton.SomeRequiredStuff;
VS
string requiredField = ExampleSingleton.Instance.SomeRequiredStuff;
但是你必须为这个属性编写getter。
此外,如果你有很多属性,它就成了一个问题:你必须编写很多静态getter。
这不是标准并反对OOP精神:你处理一个对象的属性,所以得到对象然后属性。
此外,如果您的值是不变的,那么它不是属性!,习惯是将字段const和public放在一起。与ulong.MaxValue一样。
为方法执行此操作看起来不错。 (再次在OOP中,方法属于对象)。如果你不想要任何静态的东西,你将不得不构建调用非静态函数的静态函数。维护起来并不愉快。