Maison  >  Article  >  interface Web  >  Apprendre les modèles de conception JavaScript (mode cas unique)_compétences Javascript

Apprendre les modèles de conception JavaScript (mode cas unique)_compétences Javascript

WBOY
WBOYoriginal
2016-05-16 15:29:301109parcourir

Définition du modèle singleton : assurez-vous qu'une classe n'a qu'une seule instance et fournissez un point d'accès global pour y accéder.

Le mode singleton est un mode couramment utilisé. Il existe certains objets dont nous n'avons souvent besoin que d'un seul, tels que les pools de threads, les caches globaux et les objets de la fenêtre du navigateur. Dans le développement js, le modèle singleton est également très largement utilisé. Imaginez, lorsque nous cliquons sur le bouton de connexion, une boîte de connexion apparaîtra sur la page, et cette fenêtre flottante est unique. Peu importe le nombre de fois que nous cliquons sur le bouton de connexion, cette fenêtre flottante ne sera créée qu'une seule fois. Par conséquent, cette fenêtre flottante de connexion convient au mode singleton.

1. Scénarios d'utilisation du mode singleton

Avant d'utiliser un mode, il est préférable de connaître les scénarios d'utilisation de ce mode. J'utilise le modèle singleton depuis si longtemps et je ne le connais même pas encore ! Quels sont les avantages spécifiques de son utilisation ?

1). Vous pouvez l'utiliser pour diviser l'espace de noms (ceci est souvent utilisé)

2). Utilisez la technologie de branchement pour encapsuler les différences entre les navigateurs (je ne l’ai jamais utilisé auparavant, c’est assez nouveau)

3). Grâce au mode singleton, le code peut être organisé de manière plus cohérente, ce qui le rend plus facile à lire et à maintenir (cela a également été utilisé)

2. Le modèle singleton le plus basique

Le singleton le plus simple est en fait un objet littéral. Il organise un groupe de méthodes et de propriétés associées.

var Singleton = {
  attr1: true , 
  attr2: 10 ,
  method1 : function(){
    alert('我是方法1');
  },
  method2 : function(){
    alert('我是方法2');
  }
};

Cet objet peut être modifié. Vous pouvez ajouter des propriétés et des méthodes. Vous pouvez également supprimer des membres existants à l'aide de l'opérateur de suppression. Cela viole en fait un principe de conception orientée objet : les classes peuvent être étendues, mais elles ne doivent pas être modifiées. Si certaines variables doivent être protégées, elles peuvent être définies dans une fermeture.

Les littéraux d'objet ne sont qu'un des moyens de créer des singletons. Tous les littéraux d'objet ne sont pas des singletons. Ceux qui sont simplement utilisés pour imiter des tableaux associatifs ou contenir des données ne sont évidemment pas des singletons.

3. Utilisez des fermetures pour créer des singletons

Le but principal de la fermeture est de protéger les données

// 命名空间
var BHX = {} ;
BHX.Singleton = (function(){
  // 添加自己的私有成员
  var a1 = true ;
  var a2 = 10 ;
  var f1 = function(){
    alert('f1');
  }
  var f2 = function(){
    alert('f2');
  }        
  // 把块级作用域里的执行结果赋值给我的单例对象
  return {
      attr1: a1 , 
      attr2: a2 ,
      method1 : function(){
        return f1();
      },
      method2 : function(){
        return f2();
      }            
  } ;
})();

alert(BHX.Singleton.attr1);
BHX.Singleton.method1();

Ce mode singleton est également appelé mode module, ce qui signifie qu'il peut organiser un lot de méthodes et d'attributs associés en modules et jouer le rôle de division de l'espace de noms.

4. Le mode Singleton est utilisé pour diviser l'espace de noms

1), empêcher la modification des déclarations globales

/*using a namespace*/

var BHX = {};
BHX.Singleton = {
  attr1: true , 
  attr2: 10 ,
  method1 : function(){
    alert('我是方法1');
  },
  method2 : function(){
    alert('我是方法2');
  }        
};
BHX.Singleton.attr1;
var attr1 = false;

De cette façon, même si nous déclarons la même variable à l'extérieur, nous pouvons empêcher attr1 d'être modifié dans une certaine mesure.

2), empêcher la modification d'autres codes sources

De nos jours, le code JavaScript sur les pages Web utilise souvent plusieurs sources, telles que le code de bibliothèque, le code publicitaire et le code de badge. Pour éviter les conflits avec votre propre code, vous pouvez définir un objet contenant tout votre propre code.

var XGP = {};
XGP.Common = {
  //A singleton with common methods used by all objects and modules
}
XGP.ErrorCodes = {
  //An object literal used to store data
}
XGP.PageHandler = {
  //A singleton with page specific methods and attributes.
}

3), utilisé comme emballage à code spécial

Dans un site Web comportant de nombreuses pages Web, certains codes sont utilisés par toutes les pages Web et sont généralement stockés dans des fichiers séparés, tandis que certains codes sont spécifiques à une certaine page Web et ne seront pas utilisés ailleurs. Il est préférable d'envelopper les deux types de code dans leurs propres objets singleton.

Nous utilisons souvent Javascript pour ajouter des fonctionnalités aux formulaires. Dans un souci de dégradation fluide, il est courant de créer d'abord une page HTML pure qui ne repose pas sur Javascript et utilise un mécanisme de soumission normal pour terminer la tâche.

XGP.RegPage = {
  FORM_ID: 'reg-form',
  OUTPUT_ID: 'reg-result',

  handleSubmit: function(e){
    e.preventDefault(); //stop the normal form submission

    var data = {};
    var inputs = XGP.RegPage.formEl.getElementByTagName('input');

    for(var i=0, len=inputs.length; i<len; i++){
      data[inputs[i].name] = inputs[i].value;
    }

    XGP.RegPage.sendRegistration(data);
  },
  sendRegistration: function(data){
    //make an xhr request and call displayResult() when response is recieved
    ...
  },
  displayResult: function(response){
    XGP.RegPage.outputEl.innerHTML = response;
  },
  init: function(){
    XGP.RegPage.formEl =$(XGP.RegPage.Form_ID);
    XGP.RegPage.outputEl = $(XGP.RegPage.OUTPUT_ID);
    //hijack the form submission
    addEvent(XGP.RegPage.formEl, 'submit', XGP.RegPage.handleSubmit);
  }
}
//invoke initialization method after the page load
addLoadEvent(XGP.RegPage.init);

5. Singleton paresseux

Le modèle singleton mentionné précédemment a un autre point commun : les objets singleton sont créés lors du chargement du script. Pour les singletons gourmands en ressources ou coûteux à configurer, il est plus raisonnable de différer l'instanciation jusqu'à ce que vous ayez besoin de l'utiliser.

Cette technique est un chargement paresseux.

Les étapes de mise en œuvre sont les suivantes :

1). Déplacez tout le code dans la méthode constructeur

2). Contrôle total sur le timing des appels (exactement ce que fait getInstance)

XGP.lazyLoading = (function(){
  var uniqInstance;

  function constructor(){
    var attr = false;
    function method(){

    }

    return {
      attrp: true,
      methodp: function(){

      }
    }
  }

  return {
    getInstance: function(){
      if(!uniqInstance){
        uniqInstance = constructor();
      }
      return uniqInstance;
    }
  }
})();

6. Technologie de branche

Le branchement est une technique utilisée pour encapsuler les différences entre les navigateurs dans des méthodes dynamiques définies au moment de l'exécution.

// 分支单例 (判断程序的分支 <浏览器差异的检测>)
var Ext = {} ;
var def = false ;
Ext.More = (function(){
  var objA = {    // 火狐浏览器 内部的一些配置
      attr1:'FF属性1'
      // 属性1 
      // 属性2 
      // 方法1 
      // 方法2
  } ;
  var objB = {    // IE浏览器 内部的一些配置
      attr1:'IE属性1'
      // 属性1 
      // 属性2 
      // 方法1 
      // 方法2             
  } ;
  return (def) &#63;objA:objB;
})();
alert(Ext.More.attr1);

Par exemple, si xhr est fréquemment utilisé sur un site Web, le code de détection du navigateur doit être réexécuté à chaque appel, ce qui sera très inefficace. Il est plus efficace d'identifier le code spécifique au navigateur une fois lors du chargement du script. C’est exactement ce que fait la technologie de branchement. Bien entendu, la technologie de branchement n’est pas toujours un choix plus efficace. Seule une branche parmi deux branches ou plus est utilisée, et les autres branches occupent de la mémoire.

Lorsque vous envisagez d'utiliser la technologie de branchement, vous devez peser le pour et le contre du raccourcissement du temps et de l'utilisation de plus de mémoire.

Ce qui suit utilise la technologie de branchement pour implémenter XHR :

var XHR = (function(){
  var standard = {
    createXhrObj: function(){
      return new XMLHttpRequest();
    }
  };
  var activeXNew = {
    createXhrObj: function(){
      return new ActiveXObject('Msxml2.XMLHTTP');
    }
  };
  var activeXOld = {
    createXhrObj: function(){
      return new ActiveXObject('Microsoft.XMLHTTP');
    }
  };

  var testObj;
  try{
    testObj = standard.createXhrObj();
    return testObj;
  }catch(e){
    try{
      testObj = activeXNew.createXhrObj();
      return testObj;
    }catch(e){
      try{
        testObj = activeXOld.createXhrObj();
        return testObj;
      }catch(e){
        throw new Error('No XHR object found in this environment.');
      }
    }
  }
})();

7. Inconvénients du modèle singleton

Maintenant que nous en savons beaucoup sur les singletons, examinons ses inconvénients.

Étant donné que le modèle singleton fournit un point d'accès unique, il peut conduire à un couplage fort entre les modules. Par conséquent, cela n’est pas propice aux tests unitaires.

En résumé, les singletons sont toujours réservés à la définition des espaces de noms et à l'implémentation de méthodes de branchement.

Grâce à l'introduction du modèle singleton sous sept aspects différents, avez-vous acquis une compréhension plus approfondie du modèle singleton ? J'espère que cet article pourra vous aider.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn