Quiero hacer una clase comprobable usando inyección de dependencia. Pero la clase crea múltiples objetos en tiempo de ejecución y pasa diferentes valores a su constructor. Aquí hay un ejemplo simplificado:
public abstract class Validator {
private ErrorList errors;
public abstract void validate();
public void addError(String text) {
errors.add(
new ValidationError(text));
}
public int getNumErrors() {
return errors.count()
}
}
public class AgeValidator extends Validator {
public void validate() {
addError("first name invalid");
addError("last name invalid");
}
}
(Hay muchas otras subclases de Validator).
¿Cuál es la mejor manera de cambiar esto, para poder inyectar un objeto falso en lugar de ValidationError?
Puedo crear un AbstractValidationErrorFactory e inyectar la fábrica en su lugar. Esto funcionaría, pero parece que terminaré creando toneladas de pequeñas fábricas e interfaces de fábrica, para cada dependencia de este tipo. ¿Hay una mejor manera?
Respuestas:
El cambio más simple para hacer que su unidad de clase sea comprobable es
Por supuesto, esto no es muy bueno. Pero le permite cubrir la clase con pruebas unitarias, después de lo cual puede comenzar a refactorizar hacia el diseño ideal, sin temor a romper el código con cambios más profundos.
Referencia obligatoria: trabajar eficazmente con código heredado .
Sin embargo, es difícil decir mucho sobre ese diseño ideal, ya que su ejemplo carece de detalles y contexto. Si nos cuenta más sobre lo que pretende evaluar y cuál es el papel de la clase evaluada, podríamos ayudarlo más.
fuente
Normalmente la solución para este problema es el patrón de proveedor:
El proveedor es algo similar a la fábrica. En este caso, volverá nuevo
ValidationError
cada vez queget
se llame.Se puede encontrar más información en el libro de Inyección de dependencias en la sección 3.3.2 (Reinyección con el patrón Proveedor).
Guice , por ejemplo, tiene un proveedor para esto. Si desea algo más sofisticado, puede usar AssistedInject .
fuente