2012-02-20 14 views
24

Soy un desarrollador de Java que es comenzando para captar toda la potencia de las inyecciones de dependencia, y de repente me di cuenta de que no hay forma de inyectar un método estático. Así que me hizo pensar: son métodos estáticos anti-patrones DI?¿Los métodos estáticos son anti patrón DI?

Más importante: si tuviera que aceptar la inyección de dependencia, ¿significa esto que debo dejar de codificar los métodos estáticos? Lo pregunto porque no hay forma de burlarse de ellos e inyectar falsos estáticos durante las pruebas unitarias, lo cual es un gran desvío para mí.

Editar: Sé que una forma común de "envolver" e inyectar un método estático existente es la siguiente:

public class Foo { 
    public static void bar() { ... } 
} 

public interface FooWrapper { 
    public void bar(); 
} 

public class FooWrapperImpl implements FooWrapper { 
    public void bar() { 
     return Foo.bar(); 
    } 
} 

... pero no estoy preguntando cómo inyectar una estática existente método ... Estoy preguntando si debería dejar de escribirlos por completo, si todo mi código (de ahora en adelante) va a adoptar la noción de DI.

Además, veo un montón de preguntas relacionadas con esto, pero no pude encontrar una coincidencia exacta que hiciera esta misma pregunta. Si ve que de hecho es una estafa de otra pregunta, por favor hágamelo saber y cerraré esta pregunta yo mismo (¡por favor no solo cierre la sesión!).

Respuesta

38

Los métodos estáticos son apropiados para cosas que no tienen el estado asociado . Algunos métodos de fábrica, métodos "puramente funcionales" como Math.sin, y similares son todos métodos estáticos perfectamente aceptables. java.lang.Math y java.util.Collections tienen muchos buenos ejemplos de métodos estáticos perfectamente aceptables.

Afortunadamente, estos métodos no necesitan inyección de dependencia ni interactúan con tales cosas; no son inusualmente difíciles de probar. No tienen dependencias que necesiten burlas ni nada.

Por otro lado, el estado estático o los métodos estáticos con estado estático asociado son completamente malvados. Eso es un antipatrón.

Frecuentemente, ayuda a definir un método como non-stateful (y por lo tanto, un método estático legítimo) si, y solo si, siempre devuelve una salida equivalente en entradas equivalentes. Esto deja en claro que, p. las consultas de bases de datos y la E/S del sistema de archivos hacen que los métodos sean concisos, ya que sus resultados variarán según lo que hay en el sistema de archivos o la base de datos.

+0

Así que si tengo un método llamado 'fizz()' y en él hago una llamada estática a un método 'Widget.buzz()', que golpea una base de datos y hace todo tipo de cambios en mi sistema de archivos local, entonces, ¿cómo pruebo 'fizz()' sin invocar todos los cambios masivos provocados por la invocación de 'Widget.buzz()'? Mi punto es que creo que debería dejar de escribir el método estático por completo para poder inyectar ese objeto correcto de 'Widget' (normal frente a falso), y luego controlar qué versión de 'buzz()' dispara en el tiempo de ejecución. ¿Pensamientos? – IAmYourFaja

+0

'Widget.buzz()' tiene un estado estático asociado: la base de datos e, implícitamente, todo el sistema de archivos. Eso es malvado 'fizz' podría tomar un argumento' Widget', y te burlarías de un 'Widget' para probar' fizz'. –

+0

Ahhh, nunca pensé en la base de datos o el sistema de archivos como con estado. ¿Qué criterios usas para definir "estado de estado"? Creo que esa es la raíz de mi malentendido. – IAmYourFaja

2

Los métodos estáticos no triviales son no compatibles con la inyección de dependencia. Simplemente haz que sean métodos de instancia de singletons.

Cuestiones relacionadas