I have a meta-search engine system, i implemented mainly using static classes. The query pre processing module consists of the following static methods
function queryPreprocessing() { }
queryPreProcessing.removeStopWords = function (query){ // code here}
queryPreProcessing.stemmer = function (w) { //code here }
queryPreProcessing.convertBoolean = function (w){ //code here}
Technically the query pre processing modules takes as input a string (the query) and performs the above named functions on it. For example:
var query = $("#textbox").val();
query = queryPreProcessing.removeStopWords(query) ;
query = queryPreProcessing.stemmer(query) ;
query = queryPreProcessing.convertBoolean(query) ;
For simplicity, it was easier for me to make all the methods static and call them when needed but my question is: Is this the best way of doing it?
4 Answers 4
Well if you want to use the Object prototype here is how I would structure it:
// uses Object.extend for the constructor https://gist.github.com/rlemon/5256375
function Query(options) {
this.value; // I would store the value in the object itself. Otherwise you should use this as a utility object and not deal with prototype.
// other defaults
Object.extend(this, options); // extend options to the object
}
Query.prototype = {
constructor: Query,
removeStopWords: function() { .. return this;},
stemmer: function() { .. return this;},
convertBoolean: function() { .. return this;} // returns itself for chaining
};
var q = new Query({ value: ' Foo Bar Hello World ' });
q.removeStopWords().stemmer().convertBoolean();
alert(q.value);
But this is how I would structure it based on how I am assuming you are using this. If the use cases changed or the requirements were not fully understood I would possibly write it a number of other ways.
Personally, I would make a custom type, Query
, and define these as methods on the prototype of Query
.
var Query = function(...);
Query.prototype.removeStopWords = function (query){ ... }
Query.prototype.stemmer = function (query){ ... }
Query.prototype.convertBoolean = function (query){ ... }
So you can call it as
var query = new Query()
.removeStopWords()
.stemmer()
.convertBoolean();
-
\$\begingroup\$ you can simplify this as
Query.prototype = { removeStopWords: function() { .. }, stemmer: function() { .. } ... };
I always like to add aconstructor
property to it as well. but it's not required. \$\endgroup\$rlemon– rlemon2013年03月27日 15:46:22 +00:00Commented Mar 27, 2013 at 15:46
Prototype is a good way, in alternative this is the pattern I use:
var QueryPreprocessing = {
init: function () {
// set config variables for closures here
var initparam = 'whatever';
return {
removeStopWords: function (query) {
//code here
},
stemmer: function (w) {
//code here
},
convertBoolean: function (w) {
//code here
}
}
}
var qp = QueryPreprocessing.init();
qp.removeStopWord('thequerystring');
//...
-
\$\begingroup\$ Thank you. How is this any better than other design patterns like the Factory or Facade? \$\endgroup\$Mozammil– Mozammil2013年03月27日 16:15:42 +00:00Commented Mar 27, 2013 at 16:15
Your code looks fine. The only change I would make is possibly factoring our a new function:
queryPreprocess.preProcessQuery = function preprocessQuery(query) {
query = queryPreprocessing.removeStopWords(query);
query = queryPreprocessing.stemmer(query);
query = queryPreprocessing.convertBoolean(query);
return query;
};
var queryRaw = $("#textbox").val();
var queryProcessed = queryPreprocess.preprocessQuery(queryRaw);
An object or class seems like way too much mental overhead for this task of composing functions.