08.08.2014

Реализация Singleton

Singleton

Singleton

Одиночка (англ. Singleton) — порождающий шаблон проектирования, гарантирующий, что в однопоточном приложении будет единственный экземпляр класса с глобальной точкой доступа.

© wiki

Реализация

Реализация

Если открыть wiki, то можно увидеть 5 примеров реализации, нормальный из них только один :]

Реализация #1.

			function Singleton() {
				#!+ if (!Singleton.__instance) {
					#! Singleton.__instance = this;
				} else {
					#! return Singleton.__instance;
				#!- }
				#! // Код конструктора
			}
			console.log(new Singleton === new Singleton); // true
		

Реализация #1.

Это классический способ, но в нем слишком много завязок на имя класса. Так что доведем его до логического конца и отвяжись от имени.

Реализация #1.1

			function Singleton() {
				var self = this.constructor; // ссылка на Singleton
				#!+ if (!self.__instance) {
					#! self.__instance = this;
				} else {
					#! return self.__instance;
				#!- }
				#! // Код конструктора
			}
		

Проблемы?

Проблемы

			console.log(new Singleton()); // [object Singleton]
			#! console.log(Singleton()); // undefined
		

Улучшаем

Решение #1.1.1: use strict

			function Singleton() {
				#!+ "use strict"
				#!- // остальной код
			}
			#!+ console.log(Singleton());
			#!- // TypeError: Cannot read property 'constructor' of undefined
		

Решение #1.1.2: Самовызывающийся конструктор

			function Singleton() {
				"use strict"
				#!+ if (!(this instanceof Singleton)) {
					#! return new Singleton;
				#!- } else ...
			}
			#! console.log(Singleton()); // [object Singleton]
			#! console.log(Singleton() === new Singleton()); // true
		

Решение #1.1.2: Самовызывающийся конструктор

Как видите, мы решили проблемы, но опять пришлось завязаться на название функции.

Решение #2

Решение #2

			function Singleton() {
				#! return Singleton.prototype.init();
			}
			#!+ Singleton.prototype.init = function () {
				#! // код конструктора
				#! this.init = function () { return this; };
				#! return this;
			#!- }
			#! console.log(Singleton() === new Singleton()); // true
		

Решение #2

Просто и красиво, но:

			var foo = Singleton();
			var bar = new Singleton();
			#! console.log(foo instanceof Singleton); // false :[
			#! console.log(bar instanceof Singleton); // false :[
		

Решение #2.0.1

			function Singleton() {
				return Singleton.prototype.init();
			}
			Singleton.prototype.init = function () {
				 // код конструктора
				#! var _this = Object.create(this);
				#!+ _this.init = function () { return this; };
				#!- return _this;
			}
			#!+ var foo = Singleton();
			#!- var bar = new Singleton();
			#! console.log(foo === bar); // true
			#! console.log(foo instanceof Singleton); // Bingo!
			#! console.log(bar instanceof Singleton); // Combo!
		

The End

Знаете ещё варинаты, присылайте мне на trash@rubaxa.org