2009-12-24 10 views
12

Para escribir el código de C# comprobable, uso DI en gran medida.¿Alguna necesidad de inyección de dependencia en Dynamic Languages?

Sin embargo, últimamente he estado jugando con IronPython y he descubierto que, como puede burlarse de cualquier método/clase/función, etc ... que desee, la necesidad de DI ha desaparecido.

¿Es este el caso de langagues dinámicos como Python?

En lugar de:

class Person(Address) { 
... 

Puede tener:

class Person() { 
... 
    // Address initialised in here. 

para lenguajes dinámicos y por lo tanto después de DI manaual para langagues dinámicas, simplemente no es necesario.

¿Algún consejo sobre esto?

+0

Esto parece ser un duplicado de la pregunta .. http://stackoverflow.com/questions/2273683/why-are-ioc-containers- innecesario-con-lenguajes dinámicos/2308494 # 2308494 –

Respuesta

10

Dependency Injection también se trata de cómo unir las cosas juntas, lo que no tiene nada que ver con la simulación de objetos dependientes. Hay una diferencia entre tener un -instance Foo que necesita una Bar -conexión de algún tipo instanciarlo directamente y hacer que se ignoran por completo cómo se obtiene esa conexión con tal de que tiene ella.

Si usa la inyección de dependencia, también obtendrá una mejor comprobabilidad. Pero lo contrario no es verdad. Una capacidad de prueba más sencilla al poder sobrescribir cualquier cosa no aporta las otras ventajas de la inyección de dependencia. Hay muchos componentes/marcos DI para Python disponibles exactamente por estos motivos.

+1

¿Cuáles son las "otras ventajas" de la inyección de dependencia? – asmaier

-2

Creo que estás presentando una pregunta que parece ser sobre las mejores prácticas, pero en realidad se trata del rendimiento en tiempo de ejecución.

Deshágase de la inyección de dependencia? ¿Cómo puede un administrador de versiones de software dormir por la noche?

Las pruebas de la función a realizar seguramente deben ralentizar el programa una o dos páginas.

// my generic function entry point - IronPython 
if func="a": 
    ... 
if func="b": 
    ... 
if func="c": 
    ... 

Puede usar Python estándar con clases ... o puede asignar punteros a funciones para que funcionen como miembros del puntero. ¿Qué clase de bestia es ...? Sé que sé. Python, creo que es difícil de definir, pero me gusta. Y me gusta y pienso mucho en la inyección de dependencia, no es que haya tenido mucho tiempo para pensar en asignarle un nombre tan largo a la práctica.

+1

Leer esto me dejó confundido. –

9

Estoy totalmente en desacuerdo con su afirmación de que la Inyección de Dependencia no es necesaria en los lenguajes de tipado dinámico. Las razones por las que DI es útil y necesario son completamente independientes de la disciplina de tipeo del lenguaje.

La principal diferencia es que DI en lenguajes de tipado dinámico es fácil y sin complicaciones: no necesita un marco de trabajo pesado y un sinfín de líneas de configuración XML.

En Ruby, por ejemplo, solo hay dos marcos DI. Ambos fueron escritos por un programador de Java. Ninguno de los dos marcos es utilizado por un proyecto solo. Ni siquiera por el autor de esos marcos.

Sin embargo, DI se utiliza en todo el lugar en Ruby.

Jamis Buck, que es el autor de estos dos marcos dio una charla llamada Recovering from Enterprise en RubyConf 2008 acerca de cómo y por qué escribió esos marcos y por qué eso era una mala idea, que es bien vale la pena ver. (Simplemente sustituya "Python" cada vez que diga "Ruby" y todo será igual de válido.)

+2

¿No es exagerado el "gazillion"? Uso DI en gran medida en C# y uso muy poca configuración XML, si es que la hay. – Darren

+1

Sí, definitivamente es una exageración. También es una exageración obsoleta, ya que los marcos DI post-.NET2 y post-Java5 tienden a usar atributos/anotaciones en lugar de XML. La idea básica es la siguiente: conectar las cosas dinámicamente en Java o C# es difícil. Es por eso que tiene sentido usar un marco DI: no me importa analizar XML o procesar anotaciones/atributos, así que dejo que alguien más haga el trabajo, que disfruta ese tipo de cosas. Pero en Python o Ruby, todo * está * cableado dinámicamente, * de todos modos *. El * idioma * en sí mismo ya es * un marco DI. No es necesario poner otro en la parte superior. –

+2

Otra forma de pensar: ¿qué hace un marco DI? Pega componentes independientes juntos. Y, ¿qué es lo que generalmente llamamos pegar componentes independientes juntos? ¡Scripting! ¿Y cómo determina qué hacer? Lee un archivo XML o un conjunto de anotaciones. ¿Y a qué solemos llamar un conjunto de instrucciones que indican cómo unir las cosas? ¡Un guión! Y lo que ejecuta esas instrucciones es un intérprete de guiones. Por lo tanto, un marco DI es solo un intérprete para un lenguaje de scripting (por lo general bastante malo, especialmente cuando se usa XML). Pero en Python * ya * tenemos eso: ¡Python! –

0

Lo intentaré de nuevo. Mi última respuesta se perdió la pregunta por una milla y se alejó del tema.

El uso de pseudo-código, la inyección de dependencias dice con:

class Person 
    def Chat() { 
    someOperation("X","Y","Z") 
    end 
end 
... 
Person.new().Chat() 

y adentro con:

class Person 
    initialize(a,b,c) 
    @a=a 
    @b=b 
    @c=c 
    end 
    def Chat() 
    someOperation(@a,@b,@c) 
    end 
end 
... 
Person.new("X","Y","Z").Chat() 

, y en general con poner el objeto y la llamada en diferentes archivos para. Propósitos de SCM.

Si "X", "Y" o "Z" son burlables (... si fueran objetos ... (!) ... (!) ...) no tienen nada que ver con si DI es bueno. De Verdad. :-)

DI es simplemente más fácil en Python o Ruby, como en muchas otras tareas, porque hay más de un enfoque de scripting, como dice Jörg; y también, por supuesto, menos de una cultura y una tendencia que dice que las constantes y los adaptadores se deben poblar en modelos y constantes globales.

En términos prácticos para mí DI es el primer paso para separar los parámetros de aplicación, constantes de API y fábricas en archivos separados para ayudar a que su informe de seguimiento de revisión parezca menos espagueti ("Fueron esos controles extra en el AppController a cambie la configuración ... o actualice el código ...? ") y más información, y más fácil de leer.

Mi recomendación: Siga usando DI ... :-)

Cuestiones relacionadas