设计模式研究(二)-Singleton
上篇:设计模式研究(一)实例比较TemplateMethod与Strategy
调用端调用一个类时,他是不需要也不会去考虑这个类是否已经被实例化的。而且把这样的监管工作交给调用端是很不负责的做法。
b)类型内部保证。
本篇先讨论单件 Singleton,单件的目标是保证一个类型只有一个实例,那么由谁来保证实例的唯一性呢?可能的方案有:
调用端调用一个类时,他是不需要也不会去考虑这个类是否已经被实例化的。而且把这样的监管工作交给调用端是很不负责的做法。
b)类型内部保证。
类型内部如何保证?
将实例创建工作放到类型内部,这样类型就可以将实例创建工作监管起来。类型可以知道内部的实例有没有被创建,甚至可以知道创建实例的工作被执行了多少次。
所以个人认为理解单件需要分为两步:
1、 监管工作谁来做?实例的监管工作需要类型自己去做。
2、 监管工作如何做?类型如何保证实例唯一就是技术实现问题了,可以看到的版本有 线程安全的、双重锁定的、延迟初始化的等。
下面使用伪代码逐步分析实例化工作放到类型内部的做法。
调用我,实例我给你
class Singleton
{
Singleton Instance = null;
// 实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
}
{
Singleton Instance = null;
// 实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
}
你只管调用,我保证唯一
class Singleton
{
Singleton Instance = null;
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
}
{
Singleton Instance = null;
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
}
你们都可以调用,我需要统计调用次数
class Singleton
{
Singleton Instance = null;
public int Count { get; set; }
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
Singleton GetInstance()
{
Count++;
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
}
{
Singleton Instance = null;
public int Count { get; set; }
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
Singleton GetInstance()
{
Count++;
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
}
想使用实例?请出示合法证件
class Singleton
{
Singleton Instance = null;
public int Count { get; set; }
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
Singleton GetInstance()
{
Count++;
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且接收一个合法的授权,这样可以知道每个授权方的调用次数,使用频率
Singleton GetInstance(string caller)
{
//Check 调用方合法性验证
if (Check(caller))
{
CallerCount(caller);
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
else
return null;
}
//记录调用方调用次数
public void CallerCount(string caller)
{
//caller Count++
}
public bool Check(string caller)
{
return true;
}
}
{
Singleton Instance = null;
public int Count { get; set; }
//实例化类型 Singleton
Singleton GetInstance()
{
Instance = new Singleton();
return Instance;
}
// 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
Singleton GetInstance()
{
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
Singleton GetInstance()
{
Count++;
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
// 实例化类型 Singleton,并且接收一个合法的授权,这样可以知道每个授权方的调用次数,使用频率
Singleton GetInstance(string caller)
{
//Check 调用方合法性验证
if (Check(caller))
{
CallerCount(caller);
if (Instance == null)
{
Instance = new Singleton();
}
return Instance;
}
else
return null;
}
//记录调用方调用次数
public void CallerCount(string caller)
{
//caller Count++
}
public bool Check(string caller)
{
return true;
}
}
欢迎一起讨论!
--------------------------补充-------------------------------
我把几种流行的 Singleton 写法发出来,省的大家再去查资料。
public sealed class MySingleton
{
static MySingleton instance = null;
MySingleton() { }
//简单写法
public static MySingleton Istance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
//线程安全
static readonly object obj = new object();
public static MySingleton SafeInstance
{
get
{
lock (obj)
{
if (instance == null)
instance = new MySingleton();
return instance;
}
}
}
//双重锁定 节约开销
public static MySingleton LockInstance
{
get
{
if (instance == null)
{
lock (obj)
{
if (instance == null)
instance = new MySingleton();
}
}
return instance;
}
}
//静态初始化
static MySingleton() { }
static readonly MySingleton staticinstance = new MySingleton();
public static MySingleton StaticInstance
{
get
{
return staticinstance;
}
}
//延迟初始化
public static MySingleton lazyInstance
{
get
{
return Lazy.staticinstance;
}
}
class Lazy
{
internal static readonly MySingleton staticinstance = new MySingleton();
static Lazy() { }
}
}
{
static MySingleton instance = null;
MySingleton() { }
//简单写法
public static MySingleton Istance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
//线程安全
static readonly object obj = new object();
public static MySingleton SafeInstance
{
get
{
lock (obj)
{
if (instance == null)
instance = new MySingleton();
return instance;
}
}
}
//双重锁定 节约开销
public static MySingleton LockInstance
{
get
{
if (instance == null)
{
lock (obj)
{
if (instance == null)
instance = new MySingleton();
}
}
return instance;
}
}
//静态初始化
static MySingleton() { }
static readonly MySingleton staticinstance = new MySingleton();
public static MySingleton StaticInstance
{
get
{
return staticinstance;
}
}
//延迟初始化
public static MySingleton lazyInstance
{
get
{
return Lazy.staticinstance;
}
}
class Lazy
{
internal static readonly MySingleton staticinstance = new MySingleton();
static Lazy() { }
}
}
作者:青羽