Forum Programmation.web Singleton en Js

Posté par  . Licence CC By‑SA.
Étiquettes :
0
9
mar.
2016

Bonjour,
Tout d'abord, je poste ici car il n'y a apparemment aucun forum dédié Js, c'est dommage car on peut faire autre chose que tu web en Js il me semble.

Bref, Js, je débute, et pour être franc, ça me rebute un peu. Je trouve ce langage très difficile à appréhender, notamment par le manque de recommandations officielles et claires, mais passons. Et comme je débute, quoi de mieux que de commencer au début du langage.

Je me posais hier la question : mais comment pourrais je faire un singleton en Js. Une petite recherche sur Qwant (c'est aussi mon ami) et je tombe sur ce fil : http://stackoverflow.com/questions/1635800/javascript-best-singleton-pattern. Ces codes sont assez moches, et horriblement long pour faire juste un singleton.

Alors, j'ai écris ce bout de code, qui me semble faire très bien l'affaire, j'explique en dessous.

'use strict';
var singleton = (function () {
    var counter = 0;
    return {
        getName: function () {
           return "singleton";
        },
        getCounter: function () {
            return counter;
        }
    };
})();

Si j'ai bien tout codé et compris : c'est une fonctione anonyme, qui est immédiatement invoquée (IIFE dans le jargon) et qui retourne un objet qui possède 2 méthodes (getName et getCounter). Comme la méthode est anonyme, elle ne peut plus être exécutée par ailleurs, et comme elle est "auto-exécutée" une seule fois, mon objet "singleton" est unique. Notons que la fonction "getCounter" permet d'accéder à un membre privé, ici "counter". On a donc de l'encapsulation en plus.

J'ai bon ?? Merci de vos avis sur la question, partage d'info, etc.

PS : Je n'arrive à indenter la ligne "var counter = 0;" avec le l'étiquette "code" du forum, désolé.

  • # la réponse de la question

    Posté par  . Évalué à 2. Dernière modification le 09 mars 2016 à 12:22.

    Oui dans l'absolu et au module.exports près ça marche.

    Maintenant, comme tu vas utiliser un require, et donc mettre un jolie module.exports, tu peux ré écrire le code comme cela :

        'use strict';
    
        var counter = 0;
        module.exports = {
          getName: function () {
              return "singleton";
          },
          getCounter: function () {
              return counter;
          },
          setCounter: function (k) {
              counter = k;
          }
        }

    Et l'utiliser comme cela

        var s = require('./single.js');
        var s2 = require('./single.js');
    
        console.log(s.getCounter());
        console.log(s2.getCounter());
        console.log(s.setCounter(10));
        console.log(s2.getCounter());
        console.log(s.getCounter());

    Une histoire de mise en cache des modules par require, http://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate

    PS : Ouais, moi aussi l'indent est moche.

    • [^] # Re: la réponse de la question

      Posté par  . Évalué à 2.

      PS : Ouais, moi aussi l'indent est moche.

      parce qu'il faut sauter une ligne avant de commencer le bloc de code par ```langage

      dans votre cas en tapant

      ```js
      ici_quatre_espace var counter='fdsdf'
      ```

      va donner

          var counter='fdsdf'
  • # Oui

    Posté par  (site web personnel) . Évalué à 2.

    Oui, ce que tu dis fait sens. Note que JavaScript n'a pas de notion de membre "privé". Pour rappel, le mot-clé var définit une variable qui a pour portée (scope, en anglais) la fonction imbriquée la plus proche, ou à défaut de fonction, au niveau global (objet window dans un contexte de page). Ici, ta variable counter est associée au scope de la fonction anonyme. Comme la fonction est anonyme et pas référencée par l'extérieur, son scope non plus ne l'est pas ; donc toute référence à counter ne peut se faire que depuis l'intérieur de cette fonction anonyme. C'est cette astuce qui fait que la variable est "privée", i.e. inaccessible depuis l'extérieur de la fonction anonyme.

  • # Super...

    Posté par  . Évalué à 1.

    ..merci à tous. Je progresse donc un peu plus dans ma compréhension de Js, cool.

  • # Recommendations

    Posté par  (site web personnel) . Évalué à 3.

    Bref, Js, je débute, et pour être franc, ça me rebute un peu. Je trouve ce langage très difficile à appréhender, notamment par le manque de recommandations officielles et claires, mais passons. Et comme je débute, quoi de mieux que de commencer au début du langage.

    C'est pour cela que Douglas Crockford a écrit son livre “JavaScript – The GoodParts”.

    Le niveau 2 du singleton est le singleton paresseux: tu écris une objet qui délègue tous ses appels à un second-objet (avec la même interface) qui crée cet objet avant l'appel à la première méthode.

    var create_counter = function(_my, _super) {
      var my = _my || {};
      var that = {};
      my.count = 0;
      that.tick() = {
        my.count+= 1;
        return my.count;
      }
      return that;
    }
    
    var create_lazy_counter = function(_my, _super) {
      var my = _my || {};
      var that = {};
      my.actual_counter = null;
    
      function delegate(meth) {
        that[meth] = function() {
          if(my.actual_counter === null) {
            my.actual_counter = make_counter();
          }
         return  my.actual_counter[meth].apply(my.actual_counter, arguments);
      }
    
      return that;
    }
    

    Dans l'exemple scolaire ci-dessus ça n'a pas trop d'intérêt mais cela peut être utilisé pour raccourcir les tenps d'intitlisation de programmes.

    • [^] # Re: Recommendations

      Posté par  . Évalué à 1.

      Merci pour le bouquin, je vais y jeter un œil.

      Pour le code, c'est un peu trop avancé pour mes petits neurones. J'espère dans quelques semaines/mois être plus à même d'apprécier un tel code.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.