4

The module pattern is described by most people as:

var module = (function() {
     // private fields
     var a, b, c;

     // private functions
      function myFunction() {}

     // public data (where you expose to outside)
     return {
       publicFunc:  function() {}
     };
})();

But the above code creates a single instance of the module. Does it really have to be a singleton?

Is the code below still a module pattern?

function module() {

   // same code

   return {
       publicFunc:  function() {}
     };
 }
North
  • 90
  • 4
Alin Ciocan
  • 3,082
  • 4
  • 34
  • 47
  • Yes, a module is supposed to be a singleton, to create multiple instances of a module doesn't really make sense, as it's a really just a "helper" function with methods you can call etc. and the whole point is just to create a closure with a private scope so the module doesn't interfere with other code. The second example is not a module, it's just a function that returns an object. – adeneo Jul 21 '14 at 09:12
  • 1
    No, it does however qualify for using it as a 'class' with public and private variables. – DoXicK Jul 21 '14 at 09:13

3 Answers3

3

Yes, a module pattern returns a singleton, but that's not really a practical limitation. You can use a module pattern to return a singleton factory function, and then invoke that factory function multiple times.

var point = (function() {
  // Add private code here to make use of module pattern.
  // If you don't have anything to keep private, then
  // module pattern is overkill, as noted in the comments
  return function(x,y) {
    return { 
      x : x,
      y: y
    }
  }
})();

var point1 = point(0,0);
var point2 = point(3,4);

Without using a factory function, you can also put your module pattern inside a loop and execute it multiple times (this isn't recommended as it is grossly inefficient):

var points = [];
for (var i=0; i<4; i++){
  points[i] = (function module() {
    // same code
    return {
      publicFunc:  function() {}
    };
  })();
}

UPDATE: Added comment inside of first example per @North and @Bergi's feedback below

I-Lin Kuo
  • 3,220
  • 2
  • 18
  • 25
  • +1, you should consider using the module scope in your example though. – Bergi Jul 21 '14 at 12:19
  • Your singleton factory function is over engineering. You should keep things as simple as possible. You could just as well have it written as `var point = function(x, y) { return {x: x, y: y}; };` – North Jul 21 '14 at 13:46
  • @North. Yes, but the overengineering is to answer the original post about the module pattern. I'll add a comment about that. – I-Lin Kuo Jul 21 '14 at 13:58
  • The gist of the module pattern is to have private state that you can change only by using the functions you expose in the returned object. You rarely need a state to be shared between all instances of your module. Usually you are interested in the instance to have its own state. But I do see where you are coming from (module = singleton). – North Jul 21 '14 at 14:38
1

Yes, modules are singletons. A car has just one engine. Creating a second one simply doesn't make sense (unless you radically change the whole design, increase the load which any struts can take, etc).

The second pattern is the "class" pattern where you have many instances that behave similarly (think a bunch of cars).

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • You can use the module pattern to create classes, though. – Bergi Jul 21 '14 at 12:18
  • 1
    @Bergi: That's not quite correct. You can have class patterns inside of your module pattern. But class and module pattern are different things and are meant to achieve different goals. You shouldn't mix the two (neither in code nor when talking about them) to avoid confusion. – Aaron Digulla Jul 21 '14 at 12:20
  • OK, I admit it's likely to confuse people, but you can (and often do: [example](http://stackoverflow.com/a/16896723/1048572), [better example](http://stackoverflow.com/a/24035506/1048572), [really large example](http://stackoverflow.com/a/9321429/1048572)) mix them. It's still a singleton: your company has just one motor factory. – Bergi Jul 21 '14 at 12:45
  • That's my point. The first example is a class pattern, not a module. In JavaScript, there is no clear distinction between the two, so it's important that the code does what the description says. Otherwise, your mental model will lead you to use the wrong expectations when you start debugging. – Aaron Digulla Jul 21 '14 at 12:56
  • My mental model includes [first-class](https://en.wikipedia.org/wiki/First-class_object) classes, so that's no problem :-) – Bergi Jul 21 '14 at 13:34
  • I have searched for the class pattern and it does not seem to look anything like the module pattern. From what I saw, it uses the JS constructor functionality `new Module();` and extensively uses `this`. I will not argue that most people see the module pattern as the javascript version of the singleton pattern. The sad part is that the most important pattern you need to know in JS is the non singleton version. You can easily use it to create a single instance of it in your application. – North Jul 21 '14 at 14:30
0

I always thought of the module pattern as the non-singleton version. In fact, I do avoid singletons as much as possible, especially if they have state. They're a nightmare from a testing perspective, especially when written as a self calling function.

For me, the module pattern is all about encapsulating state. If I only use a single instance of the module, I just call it a singleton module.

Here is an article that catches the gist of it, at least how I see it.

North
  • 90
  • 4