Is trying to imitate a interface/abstract class in javascript bad practice - javascript

I am writing some code in Node.js that jumped out at me as being better structured using the strategy pattern. Coming from .Net I would create the interface the rest were based on and move from there, in JavaScript this is not so clear cut.
I understand as a prototypical language JavaScript does not have the notion of interface inheritance, so I am not sure what I have done is a smell or not, as I cant seem to find references, apart from one blog post which tries to infer an interface by using a base abstract class which forces the inheriting classes to implement the function (as it throws).
My base class
QueryStrategy = function () {
};
QueryStrategy.prototype.create = function(){
throw new Error("Not Implemented");
}
module.exports = QueryStrategy;
Implementation 1
var util = require('util');
var QueryStrategy = require('./queryStrategy');
SelectQueryStrategy = function (query) {
this.parameters = query.parameters || [];
this.entity = query.entity || '';
};
util.inherits(SelectQueryStrategy, QueryStrategy);
SelectQueryStrategy.prototype.create = function () {
var self = this,
params = self.parameters,
paramList = self.parameters.length >= 1 ? '' : '*';
for (var i = 0; i < params.length; i++) {
var suffix = i === (params.length - 1) ? '' : ', ';
paramList = paramList + params[i].key + suffix;
}
return util.format("SELECT %s FROM %s", paramList, self.entity);
};
module.exports = SelectQueryStrategy;
Currently the base does not have any shared functions, or properties. Shared functions will come, properties, because of the prototypical chain search i didn't see the point of adding the "shared" properties as they are overwritten by the instances created (please if this is wrong, let me know).
Is this an acceptable approach or should I disregard inheritance in this instance. There may be some type checking and it would make it easier if your could infer the the type to one (i.e. they must all be of the Type QueryStrategy) but I don't want my .Net prejudice to take over here.
Alternative Approach
Firstly, i am not trying to sell books here, i am just reading a lot around the subject with books that i have, but want to give credit where its due.
Based on the couple of comments, it is correct to say that the type inference won't really make any difference here and possibly should be just left down to Duck Typing to check, and maybe trying to slot something in that is not defined in the language is not the best approach. I have read in Addy Osmani Javascript patterns about interfaces, although my implementation was not the same, and although interface usage is acceptable, it is probably not needed.
It might be simpler to keep the strategy approach but with a different implementation, one that is outlined in Javascript Patterns by Stoyan Stefanov, where you have one implementation and based on some form of configuration you know which strategy to use.
Pseudo Sample
QueryBuilder = function () {
this.types = [];
}
QueryBuilder.prototype.create = function (type, query) {
var strategy = types[type];
strategy.create(query);
};
QueryBuilder.types.Select = {
create: function (query) {
params = query.parameters,
paramList = query.parameters.length >= 1 ? '' : '*';
for (var i = 0; i < params.length; i++) {
var suffix = i === (params.length - 1) ? '' : ', ';
paramList = paramList + params[i].key + suffix;
}
return util.format("SELECT %s FROM %s", paramList, query.entity);
}
};
That might be a cleaner way to go, one thing i am note sure about is if I should add types to the prototype, but I guess in this simple case it wouldn't be needed, but in a more complex scenario you could have a lot of strategies and in one file might need to be abstracted out.
is this a more acceptable approach?
What I ended up with
I looked around and tried to understand more about Duck typing, Pros and Cons etc. and tried to simplify my design based on some of the comments and answer I received. I stuck with the strategy-ish approach in that every strategy defined the same function(s), essentially encapsulating what varied across the implementations and giving them a common contract for want of a better term.
One thing that changed was the base class/interface which, as correctly pointed was not doing anything constructive was removed, each strategy is independent (so not 100% in the classical representation of the pattern) they, as stated just define the same create function.
From the place where the nested ifs and switches once belonged has been replaced with a single switch which decides which query strategy to use based on the type of query type requested. This could be re-factored into a factory later on, but for now it serves its purpose:
Query.prototype.generate = function () {
var self = this,
strategy = undefined;
switch (this.queryType) {
case "SELECT":
strategy = new Select(self);
break;
case "INSERT":
strategy = new Insert(self);
break;
case "UPDATE":
strategy = new Update(self);
break;
case "DELETE":
strategy = new Delete(self);
break;
}
return strategy.create();
};
Each strategy is independently tested, and i feel this is easier to maintain as if something fails, it will fail in one place and investigation will be easier based on the unit tests. Obviously there is a trade off, more files, and a slightly more complex structure...we will see what happens.

It is an acceptable approach but it isn't really going to benefit you in any way, and may make this piece of code more difficult to maintain. The Strategy patterns are really only beneficial in languages with static typing. You could look into TypeScript, as another commenter mentioned.
In JavaScript you're going to rely more on "Duck Typing"...If it looks like a duck, smells like a duck, it's probably a duck.
http://en.wikipedia.org/wiki/Duck_typing

Related

Prototype (separately) and constructor (separately) on real examples from sites?

Read about constructors in functions:
function Animal(name) {
this.name = name;
this.canWalk = true;
}
var animal = new Animal("Hedgehog");
and also about prototypes:
Animal.prototype.draw = function () {
}
But until the end I did not understand exactly how they reduce the code and, in principle, improve the life of programmers. Why? Because it is better understood on real examples from sites and not on examples of animal or "hedgehogs" of all sorts.
An example from my personal experience: I started the cycles well when I needed to prescribe a function for 30 images, but instead of 30 functions I passed one function into a cycle and reduced it the way the code, so I understood the whole essence of the cycle, and not just memorized its anatomy. That would be for learning resources to make examples of real projects beginners would not ask 100 questions of the same type.
Therefore, I have such questions:
Can you write here how the code would look at first without a prototype and then with a prototype on some small example from the site? Or an example that could be implemented on which site.
Can you write here how the code would look at first without a constructor and then with a prototype on some small example from the site? Or an example that could be implemented on which site.
But do not post in the responses or comments a link from the GitHuB with a large code. Just give a small example here. And it is desirable not an example from the game, but from the site
Using an object constructor is a way to initialize an instance with a specific functionality. In most cases it is used to initialize properties with values (like in your code), but can be used for other things as well.
Let use more realistic example - I can initialize a few users object simply by object literals:
const user1 = {
id: 'usr123',
name: 'Max',
questions: 4
}
const user2 = {
id: 'usr124',
name: 'Danny',
questions: 2
}
But there are few problems with this approach.
First, it can be tedious when used a lot.
Second, it's harder to distinguish it from other objects.
Both of these issues can be solved with construction function:
function User(id, name, questions) {
this.id = id;
this.name = name;
this.questions = questions ? questions : 0;
}
const user1 = new User('usr123', 'Max', 4);
const user2 = new User('usr125', 'Ben'); // default questions value would be 0
const isUser = user1 instanceof User; // true
Prototype is a special object which can be used on Objects which has a constructor function (Well, all objects are descendant of Object, but let's leave this aside for a moment). The basic idea is - if I have 100 user objects - I might have some use for have a special properties or logic which relevant for all of them, and not specific for a single instance. For example, let's assume that in case of error, I would like to log all the data of the users.
I can create a special function which get and object and do this:
function userToString(user) {
return user.id + ':' + user.name + '[' + user.questions + ']'; // usr123:Max[4]
}
This would work, but harder to maintain, since it is not really part of "User".
I large projects I would probably put this function in a file with other utilities function, and call it every time i would like to use it.
Another option is to include it as part of the prototype:
User.prototype.toString() {
return this.id + ':' + this.name + '[' + this.questions + ']';
}
user1.toString(); // usr123:Max[4]
I would strongly suggest to using ES6 standard (at least). It's exist for several years, it looks much more intuitive and do some of the complex work for you.
In ES6 this code would look like this:
class User {
constructor(id, name, questions) {
this.id = id;
this.name = name;
this.questions = questions ? questions : 0;
}
toString() {
return this.id + ':' + this.name + '[' + this.questions + ']';
}
}
Look nicer isn't it? but it basically the same. This ES6 syntax is simply sugar coating for the older syntax you've included in your question.

Are there any downsides to changing a value of a JavaScript WeakMap key/value pair without using the WeakMap.set method?

I'm just beginning to learn the use cases for the ES6 WeakMap feature. I've read a lot about it, but I haven't been able to find an answer for this particular question.
I'm implementing a Node.js Minesweeper game for the terminal - just for fun and practice. I've created a class called MineBoard that will store all the necessary data and methods for the game to operate. I want some members, such as _uncoveredCount (number of squares uncovered) and _winningCount (number of squares uncovered needed to win) to remain unaccessible to the user. Although this game isn't going into production, I'd still like it to be uncheatable ;) - and the naming convention of the _ prefix to signal private members is not enough.
To do this - I've implemented a WeakMap to store the two above examples in, and other private members.
METHOD 1:
let _mineBoardPrivateData = new WeakMap();
class MineBoard {
constructor(size, difficulty) {
this.size = size || 10;
this.difficulty = difficulty || 1;
_mineBoardPrivateData.set(this, {});
_mineBoardPrivateData.get(this).winningCount = someMethodForDeterminingCount();
_mineBoardPrivateData.get(this).isGameOver = false;
_mineBoardPrivateData.get(this).uncoveredCount = 0;
//more code
}
generateNewBoard() {
//code
}
uncoverSquare() {
//more code
_mineBoardPrivateData.get(this).uncoveredCount++;
}
//more code
}
It is much easier for me to do it this way above - and also much easier on the eyes. However, most of the examples of WeakMap implementations I've seen follow the style below.
METHOD 2:
let _winningCount = new WeakMap();
let _isGameOver = new WeakMap();
let _uncoveredCount = new WeakMap();
//more instantiations of WeakMap here
class MineBoard {
constructor(size, difficulty) {
this.size = size || 10;
this.difficulty = difficulty || 1;
_winningCount.set(this, someMethodForDeterminingWinningCount() );
_isGameOver.set(this, false);
_uncoveredCount.set(this, 0);
//more private data assignment here
}
generateNewBoard() {
//code
}
uncoverSquare() {
//more code
_uncoveredCount.set(this, _uncoveredCount.get(this) + 1);
}
//more code
}
So my question is - are there any drawbacks to using Method 1 that I am not seeing? This makes for the simpler solution and IMO easier to read and follow code.
Thank you!
You can (and should) use the first method. There are no drawback to using the first method and it probably is more efficient anyways since you're only creating a single object per MineBoard instance. It also means that adding/removing private properties is much easier. Additionally, from inside your MineBoard instance you would be able to easily iterate over all the private properties just using Object.keys(_mineBoardPrivateData.get(this)) (try doing that with the second method).

Is it possible to 'import' part of a namespace (a module) into the current scope?

I have one module called functionalUtilities which contains a number of utility functions. An abbreviated version looks something like this:
MYAPP.functionalUtilities = (function() {
function map(func, array) {
var len = array.length;
var result = new Array(len);
for (var i = 0; i < len; i++)
result[i] = func(array[i]);
return result;
}
return {
map:map,
};
})();
I then have a second module which contains core code:
MYAPP.main = (function() {
//Dependencies
var f = MYAPP.functiionalUtilities;
//Do stuff using dependencies
f.map(...)
})()
It seems messy and annoying having to remember to type f.map each time I want to use map. Of course, in the dependencies, I could go though each of my functionalUtilities typing:
var map = f.map,
forEach = f.forEach,
etc.
but I wondered whether there is a better way of doing this? A lot of articles on namespacing that I've read mention aliasing, but don't suggest a way to sort of 'import all of the contents of an object into scope'.
Thanks very much for any help,
Robin
[edit] Just to clarify, I would like to use my functional utilities (map etc) within MYAPP.main without having to preface them every time with f.
This is possible by going through each function in MYAPP.functionalUtilities and assigning to a locally scoped variable within MYAPP.main. But the amount of code this requires doesn't justify the benefit, and it's not a general solution.
As I said in the comment. There is no real way of automatically defining local variables out of object properties. The only thing that comes to my mind is using eval:
for (var i in MYAPP.functiionalUtilities) {
eval("var " + i + " = MYAPP.functiionalUtilities[i];");
}
But I wouldn't use this method, since you could have object properties with strings as keys like this:
var obj = {
"my prop": 1
};
"my prop" might be a valid key for an object property but it's not a valid identifier. So I suggest to just write f.prop or define your local variables manually with var prop = f.prop;
EDIT
As Felix Kling mentioned in the comment section, there is in fact another way of achieving this, using the with statement, which I don't really know much about except for that it is deprectated.
Here's a late answer - I feel like adding to basilikum's answer.
1) The with keyword could be useful here!
with(MYAPP.functiionalUtilities) {
map(console.log, [ 'this', 'sorta', 'works', 'quite', 'nicely!' ]);
// Directly reference any properties within MYAPP.functiionalUtilities here!!
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
The with keyword is, in some ways, intended for exactly this situation. It should, of course, be noted that the mozilla developer link discourages use of with, and with is also forbidden in strict mode. Another issue is that the with statement causes its parameter to become the head of the scope chain, which means that it will always be checked first for all identifiers for all statements within the with block. This could be a performance hit.
2) An improvement to basilikum's answer
While a function call cannot add items to its parent-frame's scope, there is a way to avoid typing out a for-loop each time you wish to add a list of items to a namespace.
// First, define a multi-use function we can use each time
// This function returns a string that can be eval'd to import all properties.
var import = function(module) {
var statements = [];
for (var k in module) statements.push('var ' + i + ' = module["' + i + '"]');
return statements.join(';');
};
// Now, each time a module needs to be imported, just eval the result of import
eval(import(MYAPP.functiionalUtilities));
map(console.log, [ 'this', 'works!' ]);
The idea here is to replace the need to write a for-loop with something like eval(import(MYAPP.functiionalUtilities));.
The danger here, as basilikum has stated, is that module properties need to be valid identifier names.

Javascript: How to get the parent key inside a function?

I've some functions, stored in a collection/array and would like to get the key (function-name) without retyping it. Is there any short way to access it?
var functions_collection = {
"function_x": function() {
var name = "function_x";
// name = this.key; <- how to get the key/function-name "function_x"?
// some more code like:
$(".function_x .button").val();
alert(name);
}
}
Edit: I'd like to avoid retyping the "function_x" inside the function itself and prefer to call it like this.key.
Sorry for the weird topic and thanks in advance!
Solution: A lot of good answers, but I was just looking for this snipped:
Object.keys(this)
I'm not sure it's what you want but you can do this :
var functions_collection = {};
(function(name){
functions_collection[name] = function(){
// use name, which is the function
alert(name);
};
})("function_x");
I'm not really sure it's better. But depending on your (unspecified) goal, there's probably a better solution.
To get the name of the objects keys, you can use Object.getOwnPropertyNames(this) or in newer browsers just Object.keys(this), and that will get you an array of all and any keys the this object has :
var functions_collection = {
function_x: function() {
var name = Object.keys(this);
console.log(name);
}
}
FIDDLE
In my opinion you´d need to change you above code since you are having anonymous functions which have no name - a change like this should work:
var functions_collection = {
'function_x' : function function_x () {
var myName = arguments.callee.name;
alert(myName);
}
}
see http://jsfiddle.net/9cN5q/1/
There are several ways you could go here. Some are good ideas, some are not.
First, some bad ideas
Bad idea: arguments.callee.name
This translates most directly to what you ask. arguments.callee is
a reference to the function you're currently in. However, it's
considered bad
practice,
and you should avoid using it unless you have a really good reason.
Bad idea: Currying
After constructing the function, bind its own name into it as a parameter:
var functions_collection = {
"function_x": function(name) {
alert(name);
},
//more functions
};
for (var name in functions_collection) {
if (typeof functions_collection[name] === "function") {
functions_collection[name] =
functions_collection[name].bind(functions_collection, name);
}
}
Currying is useful for lots of things in JavaScript, and it's a great idea in many situations. Not here, though, and I'll explain why below.
Bad idea: Use a local parameter and iterate through the containing object
var functions_collection = {
"function_x": function(name) {
alert(name);
},
//more functions
};
for (var name in functions_collection) {
if (typeof functions_collection[name] === "function") {
functions_collection[name](name);
}
}
Of course, the obvious problem with this one is that you might not want to call every function in the collection at once. The more fundamental problem is that it continues the trend of dangerously tight coupling. This is a bad thing, potentially a Very Bad Thing that will cost you all kinds of headaches down the line.
Now the "right" way
Change your whole approach. Forget trying to recycle class names from your HTML; just keep it simple.
Good idea: Use a local variable
Who cares what you name your functions? If you know which HTML classes you want them to touch, just code them that way.
var functions_collection = {
"function_x": function() {
var name = "function_x"; //or "button" or any other class name
alert(name);
},
//more functions
};
functions_collection.function_x();
Good idea: Pass a parameter
You're already calling the function, right? So there's probably already code somewhere with access to the name you want.
var functions_collection = {
"function_x": function(name) {
alert(name);
},
//more functions
};
functions_collection.function_x("function_x"); //or any other class name
Now you can use function_x on any class in your HTML, even if it doesn't match the function name:
functions_collection.function_x("function_y");
functions_collection.function_x("class_z");
functions_collection.function_x("button");
I've saved the simplest for last because I think you're making a mistake by trying to be "clever", if that makes sense. There are significant risks in your approach, and the payoff isn't going to be worth it.
Why the bad ideas are bad and the good ideas are good
Other than the arguments.callee.name option, the reason 2 and 3 are bad in this case is tight coupling. You're coupling function_x to the structure of functions_collection; you're coupling behavior to a variable name; and worst of all, you're coupling JS variables to the class names of HTML elements. This will make your code extremely fragile, and when you want to change something (and you will), get ready for a world of hurt.
For example, what happens if you reorganize your HTML? The page probably breaks, since the structure of your JS has to match the classes in your HTML/CSS. You'll have to rename or rewrite functions_collection and all others like it, or else you'll have to carefully plan new HTML around the JS you already have.
What happens if you want to use a JS minifier? Depends, but if you allow it to change member names in object literals, it completely breaks everything and you have to start over with one of the "good" ideas.
Now, what do you get in exchange for this inflexibility? You save an extra line at the beginning of each function. Not worth it, IMHO. Just bite the bullet and keep it simple.
Supposing that the variable name has the same name as its containing function:
var keys = [];
for (var p in functions_collection) {
if (typeof(functions_collection[p]) == 'function') {
keys.push(p);
}
}
And there you have it, an array with all the function names.

Javascript OOP - Best practices when validating objects via interface or prototype

I am learning more advanced OO tactics for javascript coming from a C# background and am wondering about how to or if its even a good idea to implement prototype based validation. For instance when an object or function requires one of its parameters to satisfy a certain interface, you could check its interface like so,
var Interface = function Interface(i) {
var satisfied = function (t, i) {
for (var key in i) {
if (typeof t !== 'object') {
return false;
}
if (!(key in t && typeof t[key] == i[key])) {
return false;
}
}
return true;
}
this.satisfiedBy = function (t) { return satisfied(t, i); }
}
// the interface
var interfacePoint2D = new Interface({
x: 'number',
y: 'number'
});
// see if it satisfies
var satisfied = interfacePoint2D.satisfiedBy(someObject);
I came up with this strategy to validate an object by its interface only, ignoring the internal implementation of the object.
Alternatively say you are using prototype-based inheritance, should you or should not validate parameters based on their prototype functions? I understand that you'd use a prototype to implement default functionality whereas an interface doesn't specify any default functionality. Sometimes the object you are passing into a function might need certain default functionality in order for that function to work. Is it better to only validate against an interface, or should you ever validate against a prototype, and if so, whats the best way to do it?
EDIT -- I am providing some more context as to why I am asking this,
Say for instance in online game design (games written mostly in javascript). There are 2 main reasons I am interested in validation within this context,
1) Providing a strong public API for modding the game if desired
2) Preventing (or atleast discouraging greatly) potential cheaters
Which requires a balance between customizability and abuse. Specifically one situation would be in designing physics engine where objects in the game react to gravity. In a realistic system, users shouldn't be able to add objects to the system that do not react to gravity. The system has a function that expresses the global effect of gravity at any given point:
function getGravityAt(x, y) {
// return acceleration due to gravity at this point
}
And objects which react have a method that uses this to update their acceleration:
function update() {
this.acceleration = getGravity(this.position);
}
The minimum thing to do might be to ensure that any object added to the system has an 'update' method, but you still aren't ensuring that the update() method really is intended to react to gravity. If only objects that inherit from a prototypical update() method are allowed, then you know at least to some degree everything in the system reacts realistically.
This is a pretty subjective question. I'll pass on the question of whether it's a good idea to do interface-based validation in Javascript at all (there may well be good use-cases for it, but it's not a standard approach in the language). But I will say that it's probably not a good idea to validate objects based on their prototypes.
If you're validating by interface at all, you're probably working with objects created by other programmers. There are lots of ways to create objects - some rely on prototypes, some do not, and while they each have their proponents, they're all valid and likely approaches. For example:
var Point = function(x,y) {
return {
x: function() { return x },
y: function() { return y }
};
};
var p = new Point(1,1);
The object p conforms to an interface similar to yours above, except that x and y are functions. But there's no way to validate that p satisfies this interface by inspecting its constructor (which is Object()) or Point.prototype. All you can do is test that p has attributes called x and y and that they are of type "function" - what you're doing above.
You could potentially insist that p has a specific ancestor in its prototype chain, e.g. AbstractPoint, which would include the x and y functions - you can use instanceof to check this. But you can't be sure that x and y haven't been redefined in p:
var AbstractPoint = function() {};
AbstractPoint.prototype.x = function() {};
AbstractPoint.prototype.y = function() {};
var Point = function(x,y) {
var p = new AbstractPoint(x,y);
p.x = "foo";
return p;
}
var p = new Point(1,1);
p instanceof AbstractPoint; // true
p.x; // "foo"
And perhaps more importantly, this makes it harder to drop in custom objects that also satisfy the interface but don't inherit from your classes.
So I think what you're currently doing is probably the best you can hope for. In my experience, Javascript programmers are much more likely to use on-the-fly duck-typing than to try to mimic the capabilities of statically typed languages:
function doSomethingWithUntrustedPoint(point) {
if (!(point.x && point.y)) return false; // evasive action!
// etc.
}
I'll reiterate, type checking is not idiomatic javascript.
If you still want type checking, Google's closure compiler is the implementation I recommend. Type checking is done statically :) It has conventions for interfaces as well as (proto)type checking.

Categories