Java实现
不考虑线程安全的写法
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// other useful methods here
public String getDescription() {
return "I'm a classic Singleton!";
}
}
这种写法的问题在于非线程安全,当两个线程同时进入if判断,且新对象还未创建时,就会产生两个不同的对象。可以通过
synchronized
来解决此问题
方式一
public class Singleton {
private static Singleton uniqueInstance;
// other useful instance variables here
private Singleton() {}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// other useful methods here
public String getDescription() {
return "I'm a thread safe Singleton!";
}
}
此种写法解决了线程安全问题,但是,由于多线程状态时,需要排队获取单例对象,所以存在性能问题。
方式二
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
// other useful methods here
public String getDescription() {
return "I'm a statically initialized Singleton!";
}
}
此种方式线程安全且不会出现多线程状态下的性能问题。但是,问题在于即使代码中不会用到该对象,在jvm中也会创建一个,还是不够完美。
方式三
//
// Danger! This implementation of Singleton not
// guaranteed to work prior to Java 5
//
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
此种方式完美解决了多线程问题且能根据需要动态创建单例对象。唯一缺点为
volatile
关键字在jdk1.5以上才支持。
两篇介绍volatile
关键字的资料:
- http://www.infoq.com/cn/articles/ftf-java-volatile
- http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
JavaScript实现
方式一
function User(){
this.name = "YiYing";
}
var Singleton = function(){
var user = new User();
this.getInstance = function(){
return user
}
}
var user = Singleton.getInstance();
此种方式跟上面Java实现的
方式二
很像,不管用不用,一上来直接创建一个对象,如果代码中不使用就会使得创建的对象冗余。
方式二
var Singleton = function(){
var user = null;
this.getInstance = function(){
if(user === null){
user = new User();
}
return user;
}
}
此种方式实现了动态创建单例对象,相对与上一种更优。
实际应用
假如一个表单上只能允许一个表格存在,现在需要提供一个表格组件给开发人员使用。此时,不希望开发人员创建多个表格对象,可以考虑这样实现
//表格组件实现部分
(function(W){
var singleton = null;
function Grid(){
this.pagination = true;
init();
}
var init = function () {
};
Grid.prototype.addRow = function (row) {
};
Grid.prototype.deleteRow = function () {
};
W.Grid.getInstance = function () {
if(singleton===null){
singleton = new Grid();
}
return singleton;
}
})(window);
//使用部分
var grid = Grid.getInstance();
grid.addRow();
下一篇:<a href="http://muchstudy.com/2016/11/28/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%BA%8C%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/">设计模式系列之二策略模式</a>
网友评论