JavaScript設計モード-単一例、モジュール
Rolf Zhang
前に『JavaScriptの小特性-対象に向ける』でJavaScriptの対象に向けた特性を紹介しましたが、対象に向かうと自然と思うのですが、それはデザインモードがありますか?js対象に向かう方式はプロトタイプに基づいているので、伝統的なタイプではなく、jsのデザインパターンも古典的なデザインパターンとは少し違っています.
デザインモードについて
まず何がデザインモードなのか教えてください.多くの人が「デザインモード」というものはとても玄妙だと思っていますが、Gof四人組の「Design Patterns」をプログラミング聖書としてあがめています.設計パターンははっきり言って、ある種類のよくある問題を特定の環境の下で解決する方法です.このような方法によってすればいいです.しかし、これはこれらのデザインモデルが全世界に通用するという意味ではなく、デザインモデルをセットして作ったものは最高のメンテナンス、最高の性能、最高のものに違いない.どんなデザインパターンが分からなくても、考えが正しければ、デザインモードを書くことができます.
あるマスターは、デザインモデルは言語の欠陥を補うものだと言いました.ここには二重の意味があります.一つは設計モードは言語に基づいています.言語に欠陥があり、能力が足りないため、設計モードは共通の解決方法を提供してこれらの不足を補う必要があります.第二に、具体的な言語と具体的な環境から離れると、ハードウエアの設計パターンを無理に当てはめることは一種の束縛であり、設計モードは絶対的に正確ではないということです.
上記の観点を理解したら、以下はjsのシングルモデルを通じて見てみます.JavaScriptのデザインパターンはどういうことですか?
シングルケースモード(Singleton)
伝統的なシングルパターンは大体こういうことです.
public class Singleton{
private static Singleton instance;
private int property;//
private Singleton(){
//
}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public void method(){// }
}
従来の単一の例モードの特徴は、プライベート構造関数を利用して、異なる場所で起動されるのが同じインスタンスオブジェクトであることを保証することである.しかし、この点はjsにとってはちょっと弱いです.jsはグローバル変数を許容しているので、単例を解決する方法は簡単です.グローバルオブジェクトを定義したら完成します.var jsSingleton = {
property:"something",
method:function(){
console.log('hello world');
}
}
コールも簡単です.類名は気にしないで、どこを訪れても同じ対象です.心配しないでください.もしあなたが怒って私に言ったら、これは餓漢式の怠け者式の一例ですか?もし本当に対象を作る時に資源を消費したり、性能に対する潔癖性がある程度になるなら、jsに伝統的な方式を真似させるしかないです.var jsLazySingleton =(function(){
var instance;
// ( )
function init (){
return {
property: 'some thing',
method: function(){}
}
}
return {
getInstance :function(){
// instance , init()
return instance || instance = init();
}
}
})();
モジュールモード(Module)jsの怠け者タイプの一例モードでは、実はもう一つの設計モード、すなわちモジュールモードが使われています.従来のソフトウェアエンジニアリングでは、モジュールモードは、クラスにプライベートとパブリックパッケージを提供する方法、すなわち私たちがよく言う「モジュール化」と定義されています.Javaの中でクラスは一つのモジュールです.属性、方法のパッケージ問題を解決しました.モジュールモードは直接言語の特性に融合しました.だからモジュールモードの言い方もあまりないです.しかし、JavaScriptというあまりにも柔軟な言語に対しては、このような最も基本的な私有化パッケージは設計モードで解決する必要がある.
JavaScriptでは、「prvate」はキーワードではなく、「prvate」として保存されています.つまり、JavaScriptには私有化という機能がありません.この問題を解決する方法は二つあります.一つは変数を定義する時に、前に下線「_」を付けて、つまり他の開発者に教えます.この変数を動かさないでください.もう一つはクローズドを利用することです.第一の方法は本当の私有ではなく、ただ一つの規範であり、もし本物の私有を実現するなら、やはり第二の方法を使うべきである.
匿名関数を作成し、直ちに実行します.この匿名関数のコードはすべて「クローズド」の中に存在し、プライベート性を得て、特定のスコープでアクセス可能なままです.方法は以下の通りです
(function () {
// 、
})();
まず、関数を括弧で定義して、関数のオブジェクトを得て、その後、後の括弧は直ちに実行します.この形式は多くのjsライブラリで見られます.例えばjQuery:(function( window, undefined ) {
......
//
window.jQuery = window.$ = jQuery;
})(window);
jQueryがwindowという大域変数を匿名関数に転送し、内部定義のjQueryをwindowに割り当てたことを見て、グローバルスコープでは「$」記号で匿名関数の内容にアクセスできます.これらを確認したら、jsモジュールモードの基本的な様子を見てみましょう.
var Module = (function () {
var my={},
privateVar = 8;//
function privateFun() {//
return ++privateVar;
};
my.publicVar = 1;//
my.moduleFun = function () {//
return privateFun();
};
return my;
}());
console.log(Module.publicVar);//1
console.log(Module.publicFun());//9
匿名関数では、私たちはMY変数に戻り、外部からのクローズドコンテンツへのアクセスインターフェースとして、クローズド内のmy以外のコンテンツはプライベート保護され、クローズドされたデータはModule変数のスコープ内でアクセスできます.はい、モジュールモードはJavaScriptの私有化の問題を解決しました.名前空間、単例、私有化パッケージを持つオブジェクトなどを定義するために利用できます.しかし、モジュールモードも恋愛小説家ではない.例えば、私達がプライベート、公共変数を定義する方法は違っています.開発中にある変数の視認性を変える必要がある時は、その出現したすべての場所で変更しなければなりません.また、JavaScriptは動的にコンパイルされた言語として、オブジェクトに属性、方法を随時追加できますが、クローズド以外で定義された方法ではプライベートデータに直接アクセスすることはできません.
より高度なモジュールモード
前述のモジュールモードは多くの開発者にとって十分ですが、モジュールモードはさらに強く、より容易に拡張されます.
拡張性
前に言ったテンプレートパターンには一つのファイルに定義しなければならないという制限があります.コードの山のような仕事をしていた人は、必ず複数のファイルに分割する意味が分かります.幸い、我々のModulesを拡張するための巧妙な方法があります.まず、匿名関数のパラメータにModuleを導入し、属性を追加してエクスポートします.以下の例は、上記のModuleを他のファイルに拡張します.(グローバルスコープでなければならない場合):
var Module = (function (my) {
my.anotherFun = function () {
// do someting...
};
return my;
}(Module||{}));// , “{}”
私たちは再びvarキーワードでModuleを定義して一致性を保証します.そしてもし以前にModuleが作成されていなかったら、ここで自動的に空のオブジェクト「-」として作成されます.このコードの運行が終わったら、私達のModuleはまた新しい公共方法Module.another Funがあります.この拡張されたModuleにはそれぞれ独自の私有属性、方法があります.導入時に自動的に作成できますので、これらのModule定義を含むファイル間は任意の順序でロードできます.ファイル間のプライベート属性の共有
現在のマルチファイル拡張Moduleにはもう一つの大きな制限があります.それは各ファイルのModuleが自分のプライベート状態を維持しています.他のファイルのプライベート属性にアクセスできません.もちろん、これも解決されます.以下は、複数ファイルのプライベート属性共有を解決する方法である.
var MODULE = (function () {
// 、 _private
// Module my._private
var my = {},
_private = my._private = {},
_seal = function (){
// ,
delete my._private;
},
_unseal = function (){
// ,
my._private = _private;
};
my.extend = function(otherModules){
// Module
_unseal();
//add other modules
_seal();// , ,
}
return my;
}());
上のModuleファイルは最初にロードされ、他の拡張機能をModule.extedでロードしなければなりません.my.extedは、実際にはjQueryは匿名関数を実行します。のようなツールで他のModuleを並列にロードする.各拡张Moduleはmy._を通しています.prvateは私有性を伝達して、しかもすべて伝わってくるmy._.を必要とします.prvateは自分の私有属性として保存しています.prvateの修正は他の拡張子Moduleに反映されます.この方法は、Ben Cherryの「閉塞とスコープチェーン」を参照する.まとめてみます
JavaScriptのシングルモデルとモジュールモードを見ましたが、JavaScriptのデザインモデルとはちょっと違っていると感嘆しましたか?これらは言語の特性の具現であり、デザインモードは言語の特性に依存しており、言語能力に対する補足である.JavaScriptのデザインパターンは不揃いではなく、多くのJavaScriptも多くの優雅なデザインモードがあり、伝統的なデザインパターンを見劣りさせます.