所以我正在开发一个中间件层。
我正在使用一个处理低级硬件交互的COM DLL,并为UI提供了一个与硬件进行IO的接口。
作为我的图层设计的一部分,我们放置了一个上下文管理器,它安排各种硬件来生成我们的应用程序可以使用的上下文。
因此,我想保证使用我的代码的开发人员只需要一个上下文管理器,然后在该上下文管理器中,我可以保证每个硬件设备只分配1个工作队列。
为了使这复杂化,在我开始添加硬件设备之前必须进行一些初始化。如果不是因为通常只通过只读属性访问单例这一事实,这将是一件简单的事情。
我知道单身模式可以使很多事情变得困难,因为它具有全局可访问性。我真的不想要,也不需要这个类具有单例的全局可用性,我只想保证在应用程序中只创建一个。
为此,我会疯狂地做这样的事情,基本上给我的单身人士一个构造函数:
public class MySingleton
{
private static MySingleton _MySingleton;
private static object singletonLock = new object();
private MySingleton(int foo1, string foo2)
{
//do init stuff
}
public static MySingleton StartSingleton(int foo1, string foo2)
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
_MySingleton = new MySingleton(foo1, foo2);
}
else
throw new Exception("Singleton already initialized");
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
public static MySingleton Instance
{
get
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
throw new Exception("Singleton must be Initialized");
}
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
}
}
答案 0 :(得分:4)
这不是疯狂的代码,但无论如何它都是单身。如果删除Instance
属性,则它将不再是单例。
全球可访问性并非让单身人士感到讨厌。令他们讨厌的是,他们直接在整个系统中使用,而无法跟踪所有这些用法。这就是为什么它在多线程代码中是如此噩梦,这就是为什么用单例内部单元测试任何东西都是如此困难。
因此,如果它是您的代码,我建议在应用程序初始化期间只创建一个对象,并使用依赖注入或普通构造函数参数传递它。如果它是一个库,你可以检查构造函数是否是第一个正在创建的对象并抛出异常,或者你可以像你一样使用静态构造函数但没有Instance
属性,迫使开发人员传递实例
与往常一样,你可以创建单身,毕竟重要的是产品的运作和顾客喜欢使用它,单身或没有单身并不重要。
答案 1 :(得分:1)
你不会疯了。单例由于被命名空间而避免了全局变量的缺点。尽管它可以通过静态函数调用进行全局访问,但它不是全局变量。而且,它是通过命名空间访问的,因此没有人可能将它放在名为temp的全局变量中,然后将其他内容分配给temp。他们应该总是通过
获得本地参考MySingleton singletonRef = MySingleton.Instance();
当它们的范围关闭时,引用就会消亡,因此它不是全局变量。
答案 2 :(得分:0)
因此,如果我只需要保证您只能创建我的对象的一个版本,那么这样的东西就会起作用:
public class MySingleton
{
private static int objectCount = 0;
private static object singletonLock = new object();
public MySingleton(int foo1, string foo2)
{
try{
Monitor.Enter(singletonLock);
if (objectCount != 0)
{
throw new Exception("MySingleton Already exsists");
}
else
{
objectCount++;
}
}
finally{
Monitor.Exit(singletonLock);
}
//do initialization stuff
}
}
显然不再是真正的单身人士了。