I would like to spend a few lines about the Implements feature, from MooTools.
Like many other frameworks / toolkits, MooTools provides utilities for DOM manupulation, effects, etc… but what i really enjoy is the way it provides writing code, by its Class function. From Wikipedia:
Every JavaScript framework has its philosophy, and MooTools is interested in taking full advantage of the flexibility and power of JavaScript in a way that emphasizes greater modularity and code reuse.MooTools accomplishes these goals in a way that is intuitive to a developer coming from a class-based inheritance language like Java with the MooTools Class object.
It is not the goal of this post to write about how i see the code readibility improved by using Class; just click here for my own Class clone to know more.
What i would like to talk about here is the Class’s feature called Implements: it is a tool to reuse code, many times confused with Extends, and it is considered confusing from many sources.
The difference between Extends and Implements should be (!) that the first involves prototype inheritance when the second adds the properties on the prototype (more in the foot links): Implements seems then a good tool to import collections in our objects (in a damn clean way!). Let see an example:
You got objects ObjectA and ObjectB; you wrote a Class Reader that reads some data (as text) from a source, processes it and returns the result.
You want to add the Reader feature on those objects but that feature needs to access the data from those objects; one object has the data stored on its this.text property and the other one on the this.otherText property.
You don’t want to change the objects’s code… you are using them in so many places yet!
This is a really clean way in which i think you can solve the problem:
// Kills the execution var DIE = function() { throw new Error("Method not implemented"); }; // Reader var Reader = new Class({ read: function() { var data = this.getData(); data = this.process(data); console.log(data); }, process: function(data){ // some operations on data, this is only as example! return data + ";"; }; // method implemented from ObjectsA and ObjectsB! getData: function(){ DIE(); } }); // ObjectA: here data is stored on this.data var ObjectA = new Class({ Implements: Reader, data: "text", getData: function(){ return this.data; } }); // ObjectB: here data is stored on this.otherData var ObjectB = new Class({ Implements: Reader, otherData: "other text", getData: function(){ return this.otherData; } }); var a = new ObjectA(), b = new ObjectB(); a.read(); // prints "text;" b.read(); // prints "other text;"
As you can see, you can implement the Reader object on objects with different interfaces, because the getData method is from them. The way to do that is really clean and a quick look on the Implements keyword will tell you which collections are implemented on the object.
The same in pure Javascript (by prototypes in this case), just to show how much more difficult to read it looks:
var DIE = function() { throw new Error("Method not implemented"); }; // Reader var Reader = function() {}; Reader.prototype.read = function() { var data = this.getData(); data = this.convert(data); console.log(data); }; Reader.prototype.convert = function(data) { return data + ";"; }; Reader.prototype.getData = function() { DIE(); }; // ObjectA var ObjectA = function() {}; ObjectA.prototype.data = "text"; ObjectA.prototype.getData: function(){ return this.data; }; for(var fn in Reader) { ObjectA.prototype[fn] = Reader.prototype[fn]; } // ObjectB var ObjectB = function() {}; ObjectB.prototype.otherData = "other text"; ObjectB.prototype.getData: function(){ return this.otherData; }; for(var fn in Reader) { ObjectB.prototype[fn] = Reader.prototype[fn]; } var a = new ObjectA(), b = new ObjectB(); a.read(); // prints "text;" b.read(); // prints "other text;"
I think the opinion about Implements can be different for every developer, you can like it or not; anyway it opens interesting scenarios and could be good to have it on the box.
Foot notes
An objection about this article, moved by a friend, is that the Javascript i wrote here doesn’t look likes Javascript (!): he meant that there are cleanest ways to write objects in pure JS, referring to Object.create .
MooTools generates function constructors, so the Javascript written here has the purpose to do the same. Also, keep in mind that Object.create is not cross-browser: to make it cross-browser, there is an hack built on function constructors!
Anyway, function constructors are also my favourite way to write object (using tool like Class, even better!)
Some links:
- http://fragged.org/mootools-pattern-fun-class-implements-extends-at-the-same-time_1359.html
- http://mootools.net/docs/core/Class/Class
- http://stackoverflow.com/questions/1720931/mootools-extends-plus-implements
- https://nerdstuckathome.wordpress.com/2012/11/14/a-class-function-to-define-classes-in-javascript-with-mootools-like-syntax/
- Object.create
- hack built on function constructors
Thanks for reading!