Webフロントエンド開発JavaScript設計モード--単体モード(The Singleton Pattern)

6308 ワード

はじめにWebフロントエンドプロジェクトの開発において、コードの構造を明確にし、読みやすく、メンテナンスしやすく、安全にすることが重要であることは言うまでもない.コードの作成をより良くするために、設計モードの関連プログラミング思想を参考にするのは比較的に役に立つと思います.以下は簡単で使いやすいプログラミングの設計パターンを紹介します.紹介のコードの例は主にJavaScriptコードによって書かれています.説明した設計思想は他のプログラミング言語ではほとんど通用します.
参照
1.Pros javascript design patterns/javascriptデザインモード(Ross Harmes and Dustin Diaz)2.Design Patterns:Elements of Reusable Object-Orinted Software/デザインモードは対象ソフトウェアに向けた基礎を多重化することができます(EricmmGaders/Johter本文).
単体モードはJavaScriptの最も基本的によく使われるモードの一つです.コードを論理要素(オブジェクト)として組織し、単一の変数(オブジェクト名)を介してアクセスする方法を提供します.
1.単体モードの主な用途:
(1)コードの名前空間を分割し、グローバル変数の数を減らし、コードの安全性を向上させる.(2)コード遅延負荷(lazy loading);(3)コード選択呼び出し(brancing)(4)…2.単体モード基本構造2.1構造
/* Basic Singleton. */
var Singleton = {
	attribute1: true,
	attribute2: 10,
	method1: function() {
	},
	method2: function(arg) {
	}
	// Other methods can go here as well.
};
2.2アクセス方法
Singleton.attribute1 = false;
var total = Singleton.attribute2 + 5;
var result = Singleton.method1();
3.名前空間を区分する
var MyNamespace = {
	findProduct: function(id) {
	...
},
// Other methods can go here as well.
}
名前空間はグローバル変数の数を減らし、コードの安全性を高めることができます.
4.プライベートメンバーを持つ単体
4.1プライベートメンバーのアンダースコア表示方法
/* DataParser singleton, converts character delimited strings into arrays. */
GiantCorp.DataParser = {
	// Private methods.
	_stripWhitespace: function(str) {
		return str.replace(/\s+/, '');
	},
	_stringSplit: function(str, delimiter) {
		return str.split(delimiter);
	},
	// Public method.
	stringToArray: function(str, delimiter, stripWS) {
		if(stripWS) {
		str = this._stripWhitespace(str);
	}
	var outputArray = this._stringSplit(str, delimiter);
		return outputArray;
	}
};
下線は、プライベートメンバを単量体オブジェクト内で表現する簡単な方法であり、このメンバがプライベートであることを示してオブジェクト内部でのみ使用される.上記の例では、キーワードthisをGiantCorp.DataParsserに変更すると、多くの場合、より保険がかかります.
下線プライベートメンバは、簡単で明瞭な構造を表していますが、プライベートメンバーは本当にこの対象のプライベートではなく、外部からもアクセスできます.
4.2プライベートメンバーはクローズドパッケージを使用する
4.2.1包装を閉じる簡単な構造
MyNamespace.Singleton = function() {
	return {};
}();
//or
MyNamespace.Singleton = (function() {
	return {};
})();
上記の2つのコード例によって作成されたMyNamespace.Singletonは同じであり、その匿名関数は、1つのオブジェクトにMyNamespace.Singletonを割り当てたものを返す.この匿名関数は、指定された括弧のペアによって直ちに実行される.
4.2.2パブリックメンバーをreturn{}に追加し、単体に戻す:
MyNamespace.Singleton = (function() {
	return { // Public members.
		publicAttribute1: true,
		publicAttribute2: 10,
		publicMethod1: function() {
			...
		},		
		publicMethod2: function(args) {
			...
		}
	};
})();
4.2.3プライベートメンバー追加:
MyNamespace.Singleton = (function() {
	// Private members.
	var privateAttribute1 = false;
	var privateAttribute2 = [1, 2, 3];
	function privateMethod1() {
		...
	}
	function privateMethod2(args) {
		...
	}
	return { // Public members.
		publicAttribute1: true,
		publicAttribute2: 10,
		publicMethod1: function() {
			...
		},
		publicMethod2: function(args) {
			...
		}
	};
})();
プライベートメンバは匿名関数に追加されます.ここに追加されたプライベートメンバは本当にプライベートメンバです.匿名関数とリターンされたオブジェクトにのみアクセスできます.
このような単体モードはモジュールモードとも呼ばれ、関連方法と属性をモジュールとして組織することができ、名前空間を分割する役割を果たしています.
プライベートメンバがクローズドパッケージを使用する利点:プライベートメンバがクローズドに入れられても、単体以外で参照されないことが保証され、オブジェクトの実装の詳細は他のコードに影響しない.
4.2.4プライベートメンバがクローズドパッケージを使用する場合、単体のパブリックメンバーとプライベートメンバの声明の文法は異なる:
(1)公共メンバー声明は対象内部に戻し、外部に私有する.
(2)プライベート属性はvarで宣言しなければならない.そうでなければ、グローバルになる.
(3).プライベート方法は、function funName(...)によって宣言し、最後の括弧の後にセミコロンを使用する必要がない.
(4)公共の属性と方法は、atributeValue:atributeValueと、methodName:function(...)によって宣言され、メンバー間はカンマで区切られます.
5.遅延の実例化(Lazy Instantiation)
この方法は資源密集型またはより大きなオーバーヘッドを配置する単量体に適しており、必要に応じて実際の例化を行う.
5.1遅延実用化コードの構造方法
4.2.3コードを例にして、構造前コード:
MyNamespace.Singleton = (function() {
	// Private members.
	var privateAttribute1 = false;
	var privateAttribute2 = [1, 2, 3];
	function privateMethod1() {
		...
	}
	function privateMethod2(args) {
		...
	}
	return { // Public members.
		publicAttribute1: true,
		publicAttribute2: 10,
		publicMethod1: function() {
			...
		},
		publicMethod2: function(args) {
			...
		}
	};
})();
手順1:すべてのコードをconstructorという方法に置いてください.
/* General skeleton for a lazy loading singleton, step 1. */
MyNamespace.Singleton = (function() {
	function constructor() { // All of the normal singleton code goes here.
		// Private members.
		var privateAttribute1 = false;
		var privateAttribute2 = [1, 2, 3];
		function privateMethod1() {
			...
		}
		function privateMethod2(args) {
			...
		}
		return { // Public members.
			publicAttribute1: true,
			publicAttribute2: 10,
			publicMethod1: function() {
				...
			},
			publicMethod2: function(args) {
				...
			}
		}
	}
})();
ステップ2:get Instance方法を返して、constructor()のロードを制御します.
/* General skeleton for a lazy loading singleton, step 2. */
MyNamespace.Singleton = (function() {	
	function constructor() { // All of the normal singleton code goes here.
		...
	}
	return {
		getInstance: function() {
		// Control code goes here.
		}
	}
})();
ステップ3:get Instance制御の実例化
/* General skeleton for a lazy loading singleton, step 3. */
MyNamespace.Singleton = (function() {
	var uniqueInstance; // Private attribute that holds the single instance.
	function constructor() { // All of the normal singleton code goes here.
		...
	}
	return {
		getInstance: function() {
			if(!uniqueInstance) { // Instantiate only if the instance doesn't exist.
				uniqueInstance = constructor();
			}
			return uniqueInstance;
		}
	}
})();
5.2遅延荷重モノマー呼び出し方法
MyNamespace.Singleton.getInstance().publicMethod1();
6.分岐(brancing)
主に場合によっては単体で異なるオブジェクトを返すために使用されます.
6.1分岐単純構造
/* Branching Singleton (skeleton). */
MyNamespace.Singleton = (function() {
	var objectA = {
		method1: function() {
			...
		},
		method2: function() {
			...
		}
	};
	var objectB = {
		method1: function() {
			...
		},
		method2: function() {
			...
		}
	};
	return (someCondition) ? objectA : objectB;
})();
ブランチ技術にはコードの冗長性があります.使う時は時間とメモリのバランスを考慮します.
7.単体モードのまとめ
単体モードは最も一般的な設計モードの一つで、特にJavaScriptプログラミングにおいて、その利点は前文で簡単に紹介されていますが、不足しているところはモジュール間の強い結合を招き、ユニットテストに不利になる場合があります.実際の応用では、単体モードは他の設計モードと結合して使用できます.異なるデザインパターンは自分の長所があり、異なる具体的な環境と需要の中で最適なものを選ぶことができます.