En el ejemplo anterior dejábamos de la mano del programador la responsabilidad de respetar las apis de los módulos que contienen las implementaciones que queremos inyectar para aislar nuestra lógica de negocio.
Tenemos una aproximación un tanto diferente, que simularía algo así como las interfaces para homogeneizar el api de todas las implementaciones.
definiríamos nuestra interfaz, definiríamos nuestro objeto donde apilaremos nuestras implementaciones, en este caso, de librerías para manejar el dom:
var interface = {}; var implementation = {}; implementation.dom = {};
Definiriamos nuestra interfaz, así como sus métodos
interface.dom = { onDocumentIsReady : function(callback){}, onWindowIsLoad:function(callback){} };
Definimos nuestra implementación de jquery, notar como extendemos al prototype los métodos de nuestra interfaz. Una vez estoy seguro que tengo los métodos, implemento en ellos mi implementación con la biblioteca en concreto, en este caso jquery, que cubre la funcionalidad requerida
implementation.dom.jquery = function(){}; implementation.dom.jquery.prototype = Object.create(interface.dom); implementation.dom.jquery.prototype.onDocumentIsReady = function(callback) { 'use strict'; $( document ).ready( function () { callback(); } ); }; implementation.dom.jquery.prototype.onWindowIsLoad = function(callback) { 'use strict'; $( window ).load( function () { callback(); } ); };
Lo mismo exactamente para dojo, otra implementación para manejar el dom que cumple mi interfaz
implementation.dom.dojo = function(){}; implementation.dom.dojo.prototype = Object.create(interface.dom); implementation.dom.dojo.prototype.onDocumentIsReady = function(callback) { 'use strict'; dojo.addOnLoad( function(){ callback(); } ); }; implementation.dom.dojo.prototype.onWindowIsLoad = function(callback) { 'use strict'; window.onload = function () { callback(); }; };
Definimos nuestro módulo, donde inyectamos la implementación que necesitemos
var moduleExample = function(domImplementation) { 'use strict'; var sayIfDocumentIsReady = function() { domImplementation.onDocumentIsReady (function () { console.log('DOCUMENT IS READY WITH LOGIC CLOSED'); }); }; var sayIfWindowIsLoad = function() { domImplementation.onWindowIsLoad(function () { console.log('WINDOW IS LOAD WITH LOGIC CLOSED'); }); }; var initialize = function(){ sayIfWindowIsLoad(); sayIfDocumentIsReady(); }; initialize(); };
Y solo nos queda inicializar nuestro modulo e inyectarle la implementación que queramos
var jqueryImplementation = new implementation.dom.jquery(); var dojoImplementation = new implementation.dom.dojo(); var module = new moduleExample(dojoImplementation);
Como veis, hay muchas maneras de solucionar una misma problemática, por eso es importante analizarlas y adoptar la que mejor resuelva nuestras necesidades.
Como siempre os dejo los ejemplos en jsbin
http://jsbin.com/favale/1
http://jsbin.com/favale/1/edit?js,output