Reputation: 7161
Everything is working as I expected. It was just an error calling the template method. I mistyped a () so I was trying template.method instead of template().method;
Anyway, if somebody would like to explain me if this is a valid design pattern or if I should go in a different way I will be definitively very grateful.
I read about the module pattern and I'm trying to implement it in some of my projects. The problem is that, in my opinion, I'm twisting it too much. I'm inspired by the google apps script style where many objects returns other objects with methods and so on and they pass arguments.
something like
object.method(var).otherMethod();
What I want to achieve is a method that receives a parameter, sets an internal variable to that parameter and then returns an object with methods that uses that variable. Here is a minified version of the code that does not work:
var H_UI =(function (window) {
var selectedTemplate,
compileTemplate = function(){},
parseTemplateFields = function(){};
//template subModule. Collect: collects the template fields and returns a JSON representation.
var template = function(templateString){
if(templateString) selectedTemplate = templateString;
return {
getHtml:function(){ return compileTemplate( parseTemplateFields( selectedTemplate ) ) } ,
collect:function(){
.. operating over selectedTemplate ...
return JSON.stringify(result)}
} };
return {
template:template
};
})(window);
If I remove the line :
if(templateString) selectedTemplate = templateString;
and replace selectedTemplate with the parameter templateString in the methods of the returned object it works as expected. I know that I cant create a set() method in the returned object and use it like this
H_UI.template().set(var)
But I find it ugly. Anyway I think that I'm messing things up. What is the best way to construct this?
Upvotes: 0
Views: 55
Reputation: 665100
Is this a valid design pattern or if I should go in a different way
Yes, enabling chaining is definitely a valid design pattern.
However, if your template()
method returns a new object, that object and its methods should only depend on itself (including the local variables and parameters of the template
call), but not on anything else like the parent object that template
was called on.
So either remove that "global" selectedTemplate
thing:
var H_UI = (function () {
function compileTemplate(){}
function parseTemplateFields(){}
// make a template
function template(templateString) {
return {
getHtml: function(){
return compileTemplate(parseTemplateFields(templateString));
},
collect: function(){
// .. operating over templateString ...
return JSON.stringify(result)
}
}
}
return {template:template};
})();
or make only one module with with a global selectedTemplate
, a setter for it, and global methods:
var H_UI = (function () {
var selectedTemplate;
function compileTemplate(){}
function parseTemplateFields(){}
return {
template: function(templateString){
if (templateString)
selectedTemplate = templateString;
return this; // for chaining
},
getHtml: function(){
return compileTemplate(parseTemplateFields(selectedTemplate));
},
collect: function(){
// .. operating over selectedTemplate ...
return JSON.stringify(result)}
}
};
})();
The difference is striking when we make two templates with that method:
var templ1 = H_UI.template("a"),
templ2 = H_UI.template("b");
What would you expect them to do? In a functional design, templ1
must not use "b"
. With the first snippet we have this, and templ1 != templ2
. However, if .template()
is a mere setter, and every call affects the whole instance (like in the second snippet), we have templ1 == H_UI
and templ2 == H_UI
.
Upvotes: 1
Reputation: 29285
If you want H_UI.template()
creates a new object every time you call template()
on it, your solution does not work. Because the variable selectedTemplate
is created only once when the immediate function is called.
However if your intent is this your solution works fine. (variable selectedTemplate
is shared for all calls to template()
).
But if you want to every call to template
creates a new object. Please tell me to write my idea
Upvotes: 1