javascriptにおける単体モードの実現

11446 ワード

単体モードはソフトウェア開発モードとして多くの対象言語に広く使用されており、Javascriptでは単体モードも非常に広範に使用されていますが、javascript言語は独特の対象言語を持っていますので、一部の伝統的な対象言語とは単体モードの思想上で一致していますが、しかし、実現するには違いがあります.
まず、従来のオブジェクト指向言語の単量体パターンの定義を見てみましょう.単量体モードは一度だけ実装され、周知のアクセスポイントを通じてアクセスできるクラスです.この定義は、従来のオブジェクト指向言語の特徴、すなわちクラスと実用化を強調しているので、従来のオブジェクト指向言語にとっては、単体モードは、そのクラスとインスタンス化の自然特性の上に構築されたものであり、キーワードclassを使用してクラスを定義し、このクラスはnewキーワードを通じて実用化できる.しかし、newによって実装される度に得られるのは同じ例であること、またはnewによってしかその構造関数を呼び出すことができないことを保証する必要があります.
更にjavascriptの中で単体のモードの定義について見てください.単体は名前空間を分割して関連方法と属性を一緒に組織する対象です.もしそれが実用化されるなら、一度だけ実用化されます.上記の定義を比較すると、ここの単体定義はその本質を対象として定義しています.伝統的な対象言語の種類ではなく、javascriptという言語は対象に基づいていることも示しています.また、実装が可能であれば、Javascriptにおいて単体定義にはいくつかの方法があるはずであり、1つまたは複数の実装が可能であるか、すなわちnewキーワードを使って単体オブジェクトを作成する方法があるが、この方法はjavascript自身の自然の特徴ではなく、newキーワードを使って作成されたオブジェクトのためであると指摘した.実際には、Fnctionを通じて、その構造関数を定義しています.(ES 6はクラスのキーワードをサポートしていますが、現在はブラウザで広くサポートされていません.).javascriptの自然な特徴をどのように使用して、単体モードを実現しますか?
 1 var Singleton={

 2     attribute1:true,

 3     attribute2:10,

 4     method1:function(){

 5 

 6     },

 7     method2:function(arg){

 8 

 9     }

10 }
ここではオブジェクトSingletonを定義しています.内部にはいくつかの属性と方法が含まれています.それをページに含めて、jsをロードする時にこのオブジェクトを作成しました.呼び出し時にSingleton.method 1を使って呼び出します.この実用化はページロードjs解析実行中に完了したものです.newキーワードを使ってこのオブジェクトを実装していません.これもjavascriptにおいて単体モードを実現することと、伝統的に対象言語に向かうこととの大きな違いです.この方法はもっと簡単で分かりやすいです.しかし、このような方法にはいくつかの欠点があります.明らかな欠点は名前空間を提供していないことです.他のプログラマもページでSingleton変数を定義したら、この単体オブジェクトを書き換えやすく混乱させます.
 1 var mySpace={};

 2 mySpace.Singleton={

 3     attribute1:true,

 4     attribute2:10,

 5     method1:function(){

 6 

 7     },

 8     method2:function(arg){

 9 

10     }

11 }
ここではまずmySpaceの名前空間を定義し、そのオブジェクトの下に単量体オブジェクトSingletonをマウントします.これは他のプログラマとの衝突や誤操作の可能性が大幅に減少します.他の人がグローバルスコープでSingleton変数を定義しても、この単体オブジェクトに汚染されません.これは、前述の定義において名前空間を分割し、関連する属性と方法を組み合わせた機能を実現する.
この方法は依然として欠点があります.この単体オブジェクトの属性と方法は全部共有しています.外部は随時アクセスして修正できます.したがって、プライベート属性と方法をシミュレーションするためにクローズドを採用します.
 1 mySpace.Singleton=(function(){

 2     var privateAttribute1=false;

 3     var privateAttribute1=[1,2,3];

 4     function privateMethod1(){

 5 

 6     }

 7     function privateMethod2(){

 8 

 9     }

10 

11     return {

12     publicAttribute1:true,

13     publicAttribute2:10,

14     publicMethod1:function(){

15         privateAttribute1=true;

16         privateMethod1();

17     },

18     publicMethod2:function(arg){

19         privateAttribute1=[4,5,6];

20         privateMethod2();

21     }

22 

23     }

24 

25 })();
ここでは、個々のオブジェクトに直接的に匿名の自己実行関数を割り当てます.この関数では、varとfunctionキーを使用して、それぞれのプライベート属性と方法を定義します.これらは、関数の外部(単体オブジェクトの外部)では直接アクセスできません.関数が実行されると、内部作用領域の空間が回収されます.これはすなわち、プライベート属性と方法をシミュレーションするためにクローズドを利用できる理由である.この関数(クローズド)では、最終的にオブジェクトに戻ります.このオブジェクトにはいくつかの公有法と属性が含まれています.外部では直接呼び出しができます.これらの公有法は、関数の内部で定義されているので、プライベート属性と方法を呼び出すことができますが、外部では、リターンされた公有方法と属性によってのみ、いくつかの動作を完了することができます.これらの属性はSingleton.prvateMethod 1を直接呼び出すことができません.これにより、この単体オブジェクトは外部から隔離されて直接にそのプライベート属性と方法にアクセスし、また外部にいくつかの共有属性と方法を提供していくつかの操作を完成させる.
この匿名関数は、実行時に作成された単体モードから多くのjsライブラリで広く使用されていますが、それでも問題があります.ページを読み込む時にそのオブジェクトを使用する必要がない場合、そのオブジェクトの作成には比較的に費用がかかります.合理的な方法は、jsの解析実行に従って直接作成するのではなく、必要な時に作成します.このような概念は不活性負荷と呼ばれています.
 1  mySpace.Singleton=(function(){

 2         var uniqueInstance;

 3         function constructor(){

 4             var privateAttribute1=false;

 5             var privateAttribute1=[1,2,3];

 6             function privateMethod1(){

 7             }

 8             function privateMethod2(){

 9             }

10             return {

11                 publicAttribute1:true,

12                 publicAttribute2:10,

13                 publicMethod1:function(){

14                     privateAttribute1=true;

15                     privateMethod1();

16                 },

17                 publicMethod2:function(arg){

18                     privateAttribute1=[4,5,6];

19                     privateMethod2();

20                 }

21 

22             }

23         }

24 

25         return {

26             getInstance:function(){

27              if(!uniqueInstance){

28                  uniqueInstance=constructor();

29              }

30                 return uniqueInstance;

31             }

32         }

33 

34     })();
ここではまず、匿名関数でプライベート変数uniqueInstanceを定義し、単体オブジェクトが作成されたかどうかを判断するハンドルとして、先ほど単量体オブジェクトに定義された属性と方法を、constructorという関数の中に置いて、この関数が呼び出されただけで、単量体オブジェクトが作成されます.そうでなければ、直接に作成されません.そして、外部に呼び出されるget Instance方法を含むオブジェクトに戻ります.この方法を呼び出した場合、まず単量体オブジェクトが存在するかどうかを判断します.存在する場合はそのまま戻します.最後に、この単体オブジェクトを呼び出す方法が必要であれば、mySpace.Singleton.getInstance()を使用します.publicMethod 1()ここでは、私達がこのように呼び出した時だけこの単体オブジェクトを作成します.そうでないと、この単体オブジェクトは自動的に作成されないので、実際に必要に応じてロードまたは不活性化されます.