A disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions.
Does anyone have an example of what he means by this?
Link to the Revealing Module Pattern referenced above
The Revealing Module pattern is a design pattern for Javascript applications that elegantly solves this problem. The central principle of the Revealing Module pattern is that all functionality and variables should be hidden unless deliberately exposed.
Module pattern. The Module pattern is used to mimic the concept of classes (since JavaScript doesn't natively support classes) so that we can store both public and private methods and variables inside a single object — similar to how classes are used in other programming languages like Java or Python.
Compare an object created by using an object literal to one created by the Revealing Module Pattern.
Here is one created as an object literal.
function makeGreeter(name){
return {
getName: function(){ return name;},
sayHello: function(){console.log("Hello, " + this.getName());}
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, George"
When you override the public method getName
on the returned object, the sayHello
method which depends on getName
picks up the change. This is because in the Object Literal style, references to public functions are made via this
, the returned object.
However, when you use the Revealing Module Pattern,
function makeGreeter(name){
var getName = function(){ return name;},
sayHello = function(){console.log("Hello, " + getName());};
return {
getName: getName,
sayHello: sayHello
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, Danny"
The RMP greeter will not pick up the override to the public getName
method. This is because when RMP functions reference other functions (both public and private), they refer to the private closure copy rather than to the public function attached to the returned object.
It is for this reason I regard the Revealing Module Pattern as an anti-pattern.
I would bind getName
to this, which, it seems, points to the content returned in RMP.
function makeGreeter(name){
this.getName = function(){ return name;};
var _sayHello = function(){console.log("Hello, " + this.getName());};
return {
getName: getName,
sayHello: _sayHello
}
}
I prefer this, though:
function makeGreeter(name){
this.getName = function(){ return name;};
var _sayHello = function(){console.log("Hello, " + this.getName());};
var API = {
getName: getName,
sayHello: _sayHello
};
return API;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With