Java实现
不考虑线程安全的写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Singleton { private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }
public String getDescription() { return "I'm a classic Singleton!"; } }
|
这种写法的问题在于非线程安全,当两个线程同时进入if判断,且新对象还未创建时,就会产生两个不同的对象。可以通过synchronized来解决此问题
方式一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Singleton { private static Singleton uniqueInstance;
private Singleton() {}
public static synchronized Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }
public String getDescription() { return "I'm a thread safe Singleton!"; } }
|
此种写法解决了线程安全问题,但是,由于多线程状态时,需要排队获取单例对象,所以存在性能问题。
方式二
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton { private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return uniqueInstance; }
public String getDescription() { return "I'm a statically initialized Singleton!"; } }
|
此种方式线程安全且不会出现多线程状态下的性能问题。但是,问题在于即使代码中不会用到该对象,在jvm中也会创建一个,还是不够完美。
方式三
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
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实现
方式一
1 2 3 4 5 6 7 8 9 10 11 12
| function User(){ this.name = "YiYing"; }
var Singleton = function(){ var user = new User(); this.getInstance = function(){ return user } }
var user = Singleton.getInstance();
|
此种方式跟上面Java实现的方式二很像,不管用不用,一上来直接创建一个对象,如果代码中不使用就会使得创建的对象冗余。
方式二
1 2 3 4 5 6 7 8 9
| var Singleton = function(){ var user = null; this.getInstance = function(){ if(user === null){ user = new User(); } return user; } }
|
此种方式实现了动态创建单例对象,相对与上一种更优。
实际应用
假如一个表单上只能允许一个表格存在,现在需要提供一个表格组件给开发人员使用。此时,不希望开发人员创建多个表格对象,可以考虑这样实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| (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();
|
下一篇:设计模式系列之二策略模式
留言
欢迎交流想法。留言会通过 GitHub Issues 保存,首次使用需要登录 GitHub。