// Singleton with public final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {...}
public void leaveTheBuilding() {...}
}
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {...}
public void leaveTheBuilding() {...}
}
// singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {...}
public static Elvis getInstance() {
return INSTANCE;
}
public void leaveTheBuilding() {...}
}
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {...}
public static Elvis getInstance() {
return INSTANCE;
}
public void leaveTheBuilding() {...}
}
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() {...}
}
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() {...}
}
——————————————————————————————————————————————————————————————————
附另一篇《参数化的Singleton》
http://book.51cto.com/art/200812/100191.htm
很多时候Singleton对唯一实例的构造过程有些"莽撞",因为要么new()一个无参数的构造函数,要么按照指定参数序列构造一个硬编码参数方式的 构造函数,这确实不够灵活,即便可以把很多判断逻辑放到静态构造函数或那个Lazy构造过程,但毕竟这都是在开发过程中定义的。
C# 硬编码方式实现僵化的参数化Singleton
public class Singleton
{
/// 参数化构造函数
private string message;
private Singleton(string message) { this.message = message; }
public string Message { get { return this.message; } }
public class Singleton
{
/// 参数化构造函数
private string message;
private Singleton(string message) { this.message = message; }
public string Message { get { return this.message; } }
/// 硬编码方式实现的参数化构造函数
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
lock(typeof(Singleton))
if (instance == null)
if ((DateTime.Now.DayOfWeek == DayOfWeek.Sunday) ||
(DateTime.Now.DayOfWeek == DayOfWeek.Saturday))
instance = new Singleton("weekend");
else
instance = new Singleton("work day");
return instance;
}
}
}
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
lock(typeof(Singleton))
if (instance == null)
if ((DateTime.Now.DayOfWeek == DayOfWeek.Sunday) ||
(DateTime.Now.DayOfWeek == DayOfWeek.Saturday))
instance = new Singleton("weekend");
else
instance = new Singleton("work day");
return instance;
}
}
}
既然直接硬编码太僵化,很多时候第一直觉是参考"依赖注入"的模式,把需要的参数注入到唯一实例中,如本书第1章介绍的,注入在.NET环境下有四种方式。
构造函数方式:这种方式在Singleton行不通,因为不允许客户程序控制Singleton类型的实例化过程。
Setter方式:通过暴露出公共实例属性(public或某些情况下internal),客户程序就可以修改唯一实例的内容,实现参数化不成问题,但同时这种方式有点太过"自由"了,无论哪里的客户程序只要可以看到相关属性就能修改,这很容易失控。这种方式备选。
接口方式:侵入性太强,而且接口方法的实现全部都在类内部,本身就是硬编码过程,解决不了问题。
Attributer方式:将通用的Attribte作为桥梁,可以在外部将需要的信息注入Singleton类型,供构造过程参考。这是可行的,但其代价相对于Singleton模式而言有点大。这种方式备选。
既然外部注入方式感觉上都不是很理想,还是让Singleton"内强"好了,一个不错的选择是借助访问配置系统(配置文件、ini文件或数据库等)。例如上面的那个问题,我们可以通过把message的内容配置在App.Config文件里来解决,其代码如下:
App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="parameterizedSingletonMessage" value="Hello world"/>
</appSettings>
</configuration>
C#
public class Singleton
{
/// 其他处理
/// ……
/// 通过访问配置实现的参数化Singleton实例构造
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
lock(typeof(Singleton))
if (instance == null)
{
/// 读取配置并进行实例化
string key = "parameterizedSingletonMessage";
string message = ConfigurationManager.AppSettings[key];
instance = new Singleton(message);
}
return instance;
}
}
}
UnitTest
Assert.AreEqual<string>("Hello world", Singleton.Instance.Message)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="parameterizedSingletonMessage" value="Hello world"/>
</appSettings>
</configuration>
C#
public class Singleton
{
/// 其他处理
/// ……
/// 通过访问配置实现的参数化Singleton实例构造
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
lock(typeof(Singleton))
if (instance == null)
{
/// 读取配置并进行实例化
string key = "parameterizedSingletonMessage";
string message = ConfigurationManager.AppSettings[key];
instance = new Singleton(message);
}
return instance;
}
}
}
UnitTest
Assert.AreEqual<string>("Hello world", Singleton.Instance.Message)
——————————————————————————————————
傲轩游戏网
傲轩游戏网