Some code may say more than a thousand words:
/**
* Represents an amount of a resource
* @param {number} amount
* @param {string} type
*/
function Resource(amount, type) {
var nAmount = amount;
var sType = type;
if (amount < 0) {
throw new IllegalArgumentException("amount has to be positive");
}
/**
* @method Resource
* @return {number} amount of the resource
*/
this.getAmount = function() {
return nAmount;
};
/**
* @method Resource
* @return {string} resource type
*/
this.getType = function() {
return sType;
};
}
/**
* Addition of two resources produces a new resource with the sum amount
* the new object uses the old one as prototype
* @param {Resource} resource
* @return {Resource} new Resource object
*/
Resource.prototype.plus = function(resource) {
if (!(resource instanceof Resource && this.getType() == resource.getType())) {
throw new IllegalArgumentException("resources don't match.");
}
var newRes = Object.create(this); // create a new object based on the current one
// execute the Resource constructor on it
Resource.call(newRes, this.getAmount() + resource.getAmount(), this.getType());
return newRes;
};
Resource objects are ValueObjects considered immutable, they return a new object on addition. Now instead of just calling "new Resource(args)" to create the new object to return, I created a new one based on the old object. This also permits inheritance.
As I'm starting to use this on all my ValueObjects (just in case I want to inherit from them some times), I started to think about it a bit more.
JavaScript doesn't allow immutable objects yet, Objects are vulnarable by direct method overwriting or calling the constructor on it. All I can do is to declare them bad habits. Unfornatunately ECMAScript5 "freeze" is not yet here, though my pattern is compatible with it.
Now as I have this "bad style" of calling the constructor on a immutable object and this code duplication, I'm thinking of creating a new function to encapsulate this procedure:
Object.recreate = function(proto, constructor, args) {
var obj = Object.create(proto);
constructor.apply(obj, args);
return obj;
};
And therefor:
Resource.prototype.plus = function(resource) {
// if ... {throw ...}
return Object.recreate(this, Resource,
[this.getAmount() + resource.getAmount(), this.getType()]);
};
Maybe anybody has a better idea for the name of this function, this is what my first though was. What do you think about this pattern? Is it over-abstraction? Should I save this for classes I'm sure I'll inherit from? Did I miss anything important?
Edit: I see I forgot to mention something important which doesn't reflect currently in this article. ValueObject's are easily cloned with Object.create, their private members are unchangable. But what about changable private members? If a set() is called on the clone, it sets on the original prototype object within the closure! As my Object.recreate recreates the closure, this problem is solved.
So, is there a better way for inheritance with private variables? Why is everyone using sugar for class creation? I've read so much about prototypalism, I still don't get the hang of it.