Pregunta

¿Alguien puede ayudar a ilustrar? Principio de inversión de dependencia en JavaScript jQuery?

Lo cual resaltaría y explicaría estos 2 puntos:

A.Los módulos de alto nivel no deberían depender de módulos de bajo nivel.Ambos deberían depender de abstracciones.

B.Las abstracciones no deberían depender de los detalles.Los detalles deberían depender de abstracciones.

¿Qué son las abstracciones o módulos de alto/bajo nivel?

Esto realmente me ayudará a entenderlo, ¡gracias!

¿Fue útil?

Solución

Yo diría que DIP se aplica en JavaScript de la misma manera que se aplica en la mayoría de los lenguajes de programación, pero hay que tener en cuenta el papel de la escritura pato.Hagamos un ejemplo para ver a qué me refiero...

Digamos que quiero comunicarme con el servidor para obtener algunos datos.Sin aplicar DIP, esto podría verse así:

$.get("/address/to/data", function (data) {
    $("#thingy1").text(data.property1);
    $("#thingy2").text(data.property2);
});

Con DIP, podría escribir código como

fillFromServer("/address/to/data", thingyView);

donde la abstracción fillFromServer poder para el caso particular donde queremos usar Ajax de jQuery ser implementado como

function fillFromServer(url, view) {
    $.get(url, function (data) {
        view.setValues(data);
    });
}

y la abstraccion view puede ser implementado para el caso particular de una vista basada en elementos con IDs thingy1 y thingy2 como

var thingyView = {
    setValues: function (data) {
        $("#thingy1").text(data.property1);
        $("#thingy2").text(data.property2);
    }
};

Principio A:

  • fillFromServer pertenece a un módulo de bajo nivel, manejando como lo hace la interacción de bajo nivel entre el servidor y la vista.Algo así como, digamos, un settingsUpdater objeto sería parte de un módulo de nivel superior, y se basaría en el fillFromServer abstracción, no en sus detalles, que en este caso se implementan a través de jQuery.
  • Similarmente, fillFromServer no depende de los detalles de los elementos DOM y sus ID para realizar su trabajo;en cambio, depende de la abstracción de un view, que para sus efectos es cualquier tipo que tenga un setValues método.(Esto es lo que se entiende por "escribir como pato").

Principio B:

Esto es un poco menos fácil de ver en JavaScript, con su escritura pato;en particular, algo como view no se deriva de (es decir,depender de) algún tipo de viewInterface tipo.Pero podemos decir que nuestro caso particular, el thingyView, es un detalle que "depende" de la abstracción view.

De manera realista, "depende" del hecho de que las personas que llaman comprendan qué tipo de métodos deben llamarse, es decir,que las personas que llaman son consciente de la abstracción adecuada.En los lenguajes habituales orientados a objetos, es más fácil ver la dependencia de thingyView explícitamente en la abstracción misma.En tales lenguajes, la abstracción estaría incorporada en una interfaz (digamos, IView en C# o Viewable en Java), y la dependencia explícita es vía herencia (class ThingyView : IView o class ThingyView implements Viewable).Sin embargo, se aplica el mismo sentimiento.


¿Por qué es esto genial?Bueno, digamos que un día necesitaba poner los datos del servidor en cuadros de texto con ID. text1 y text2 en lugar de <span />s con identificaciones thingy1 y thingy2.Además, digamos que este código se llamaba con mucha frecuencia y la evaluación comparativa reveló que se estaba perdiendo rendimiento crítico mediante el uso de jQuery.Entonces podría simplemente crear una nueva "implementación" del view abstracción, así:

var textViewNoJQuery = {
   setValues: function (data) {
        document.getElementById("text1").value = data.property1;
        document.getElementById("text2").value = data.property2;
   }
};

Luego inyecto esta instancia particular de la abstracción de vista en mi fillFromServer abstracción:

fillFromServer("/address/to/data", textViewNoJQuery);

Esto requirió No cambios a fillFromServer código, porque dependía sólo de la abstracción de un view con un setValues método, y no en los detalles del DOM y cómo accedemos a él.Esto no solo es satisfactorio porque podemos reutilizar el código, sino que también indica que hemos separado claramente nuestras preocupaciones y hemos creado un código muy preparado para el futuro.

Otros consejos

EDITAR:

Esto muestra el uso de DIP en JavaScript sin formato y un menos completo Ejemplo de jQuery.Sin embargo, la siguiente descripción se puede aplicar fácilmente a jQuery.Vea el ejemplo de jQuery en la parte inferior.

La mejor manera es aprovechar el "Patrón de adaptador", también llamado "envoltorio".

Un Adaptador es básicamente una forma de envolver un objeto o módulo de tal manera que proporcione el mismo interfaz consistente a su dependientes.De esa manera, la clase dependiente (normalmente una nivel más alto class) puede intercambiar fácilmente módulos del mismo tipo.

Un ejemplo de esto sería un alto nivel (o supra) módulo que depende de los módulos Geo/Mapping.

Analicemos esto.Si nuestro módulo supra ya utiliza GoogleMaps pero luego la administración decide que es más barato utilizar LeafletMaps, no queremos tener que reescribir cada llamada a método desde gMap.showMap(user, latLong) a leaflet.render(apiSecret,latLong, user), et al.Sería una pesadilla tener que portar nuestra aplicación de un marco a otro de esta manera.

Lo que nosotros queremos:Nos gustaría un "envoltorio" que proporcione lo mismo interfaz consistente al módulo supra, y haga esto para cada módulo de nivel inferior (o infra módulo).

A continuación se muestra un ejemplo muy sencillo:

var infra1 = (function(){
    function alertMessage(message){
        alert(message);
    }

    return {
        notify: alertMessage
    };
})();

var infra2 = (function(){
    function logMessage(message){
        console.log(message);
    }

    return {
        notify: logMessage
    };
})();


var Supra = function(writer){
    var notifier = writer;
    function writeMessage(msg){
        notifier.notify(msg);
    }

    this.writeNotification = writeMessage;
};


var supra;

supra = new Supra(infra1);
supra.writeNotification('This is a message');

supra = new Supra(infra2);
supra.writeNotification('This is a message');

Tenga en cuenta que no importa qué tipo de módulo de nivel inferior "escribir" usemos (en este caso infra1 y infra2), no tenemos que reescribir ninguna implementación de nuestro módulo de alto nivel, Supra.Esto se debe a que DIP aprovecha dos principios de diseño de software diferentes:"IoC" (Inversión de Control) y "DI" (Inyección de Dependencia).

La mejor analogía que he encontrado es la imagen que se muestra a continuación.

enter image description hereToda fuente eléctrica depende de una interfaz específico para los tipos de cosas que necesitan conectarse a él.

Descripción de jQuery:

Este patrón se puede aplicar fácilmente al uso de marcos como jQuery.Un ejemplo sería el sencillo identificador DOM-Query.Podemos usar DIP para permitir un acoplamiento flexible, de modo que si alguna vez decidimos cambiar de marco o confiar en métodos nativos de DOM-Query, el mantenimiento sea fácil:

var jQ = (function($){

    return {
        getElement: $
    };
})(jQuery);

var nativeModule = (function(){

    return {
        getElement: document.querySelector
    };
})();


var SupraDOMQuery = function(api){
    var helper = api, thus = this;

    function queryDOM(selector){
        el = helper.getElement(selector);
        return thus;
    }

    this.get = queryDOM;
};


var DOM;

DOM = new SupraDOMQuery(jQ);
DOM.get('#id.class');

DOM = new SupraDOMQuery(nativeModule);
DOM.get('#id.class');

Obviamente, este ejemplo necesitaría mucha más funcionalidad para ser práctico, pero espero que entienda el mensaje.

Básicamente, las diferencias entre un Adaptador y una Fachada se vuelven algo triviales.En una fachada, probablemente esté viendo un único módulo que envuelve una API u otro módulo;mientras que un Adaptador crea una API de Facade consistente para cada uno de sus módulos y explota esta técnica para evitar el acoplamiento estrecho.

La mayoría de los libros sobre patrones de diseño de JavaScript analizan el patrón del adaptador;uno que analiza específicamente un 'Adaptador jQuery' es Aprender patrones de diseño de JavaScript por Addy Osmani publicado por O'Reilly -- aquí.Sin embargo, también recomiendo investigar Patrones de diseño de JavaScript profesionales por Dustin Díaz y Ross Harmes publicado por presionar -- Échale un vistazo.Sin embargo, creo que es importante comprender el contexto en el que planeamos implementar DIP en relación con jQuery.

Espero que esto ayude a aclarar las cosas :)

Encontrados algunos ejemplos útiles aquí .

Dependencia principio de la inversión en JavaScript jQuery

No hay alguna conexión entre DI y jQuery. DI es todo acerca de la estructura y la aplicación de montaje de los compoents. jQuery es un contenedor cercano alrededor de DOM, nada más, no tiene ninguna estructura o componentes.

Puede utilizar DI para el montaje su aplicación JavaScript, pero sería la misma apariencia no importa ¿Utiliza jQuery o no.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top