js单例模式及应用场景

单例模式

单例就是保证一个类只有一个实例,实现方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。

单例模式的思路:

一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用 getInstance 名称)。那么当我们调用这个方法时,如果类持有的引用不为空就返回该引用,否者就创建该类的实例,并且将实例引用赋值给该类保持的那个引用再返回。同时将该类的构造函数定义为私有方法,避免其他函数使用该构造函数来实例化对象,只通过该类的静态方法来得到该类的唯一实例

对象字面量

在js中,实现单例最简单的方式就是使用对象字面量

var mySingleton = {
	property: 'something',
	property2: 'something else',
	method1: function() {
		console.log("hello world");
	}
}
var s1 = mySingleton;
var s2 = mySingleton;
console.log(s1 === s2); // true

很简单的创建了一个单例,不足之处在于没有什么封装性,所有的属性和方法都是暴露的。对于一些需要使用私有变量的情况就不适用了。我们可以扩展该对象,添加自己的私有成员和方法,然后使用闭包在内部封装这些变量和函数声明,只暴露你想暴露的属性和方法

var mySingleton = function() {
	// 声明私有变量和方法
	var privateVariable = 'something private';
	function showPrivate() {
		console.log(privateVariable);
	}
	// 共有变量和方法
	return {
		publicMethod: function() {
			showPrivate();
		},
		publicVar: 'the public can see this!'
	}
};
var singleton = mySingleton();
singleton.publicMethod(); // something private
console.log(singleton.publicVar); // the public can see this!

以上代码只是实现返回了对象作为入口点,通过入口对象可以访问到内部封装的属性和方法,这个入口对象并不是单例,实现JS单例模式主要的思路是:使用数据缓存来存储该单例,用作判断单例是否已经生成

var SingletonTester = (function(){
	// 构造器函数
	function Singleton(options){
		options = options || {};
		this.name = 'SingletonTester';
		this.pointX = options.pointX || 6;
		this.pointY = options.pointY || 10;
	}
	// 缓存单例的变量
	var instance;
	// 静态变量和方法
	var _static = {
		name: 'SingletonTester',
		getInstance: function(options) {
			if (instance === undefined) {
				instance = new Singleton(options);
			}
			return instance;
		}
	};
	return _static;
})();

var singletonTest = SingletonTester.getInstance({
	pointX: 5,
	pointY: 5
})

console.log(singletonTest.pointX); // 5
console.log(singletonTest.pointY); // 5

var singletonTest1 = SingletonTester.getInstance({
	pointX: 10,
	pointY: 10
})
console.log(singletonTest1.pointX) // 5
console.log(singletonTest1.pointY) // 5

应用场景

1.Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗?

2.windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例

3.应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加

4.Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源

5.数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗

6.多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制

7.操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统

8.HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例

单例模式应用的场景一般发现在以下条件下:

  (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。

  (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

猜你喜欢

转载自blog.csdn.net/liu_jun_tao/article/details/81236713