ref – https://github.com/RestlessThinker/Javascript-Interface/blob/master/interface.js
Interfaces in JS are implemented like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// Constructor var Interface = function (name, methods) { if (arguments.length != 2) { throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2."); } this.name = name; this.methods = []; for (var i = 0, len = methods.length; i < len; i++) { if (typeof methods[i] !== 'string') { throw new Error("Interface constructor expects method names to be passed in as a string."); } this.methods.push(methods[i]); } }; // Static class method. Interface.ensureImplements = function (object) { if (arguments.length < 2) { throw new Error("Function Interface.ensureImplements called with " + arguments.length + "arguments, but expected at least 2."); } for (var i = 1, len = arguments.length; i < len; i++) { var interface = arguments[i]; if (interface.constructor !== Interface) { throw new Error("Function Interface.ensureImplements expects arguments two and above to be instances of Interface."); } for (var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j]; if (!object[method] || typeof object[method] !== 'function') { throw new Error("Function Interface.ensureImplements: object does not implement the " + interface.name + " Interface. Method " + method + " was not found."); } } } }; |
simply use them whenever you do Constructor dependency injection, or set dependency injection.
Make sure the incoming object implements the functions (duck typing). If it does, then that means the inner objects calls the methods (Inversion of control).
The allows you to easily test the container and the incoming part.