Tuve una discusión interesante hoy con otro desarrollador sobre cómo abordar una clase con un método que acepta una cadena y genera una cadena.
Imagine algo como lo siguiente que está completamente inventado con el propósito de ejemplo
public string GetStringPart(string input)
{
//Some input validation which is removed for clarity
if(input.Length > 5)
return input.Substring(0,1);
if(input.Substring(0,1) == "B")
return input.Substring(0,3);
return string.empty;
}
Una función que tiene cierta lógica basada en su entrada de cadena se agrega a un proyecto usando DI y tiene un Contenedor DI en su lugar. ¿Agregarías esta nueva clase con una interfaz y la inyectarías donde sea necesario, o la convertirías en una clase estática? ¿Cuáles son los pros y los contras de cada uno? ¿Por qué querrías (o no) hacer que esto se use con la inyección del constructor en lugar de solo acceder cuando sea necesario en cualquier lugar?
Respuestas:
No hay ninguna razón por la que esto deba inyectarse. Esto es solo una función, no tiene dependencias, así que simplemente llámelo. Incluso puede ser estático si lo desea, ya que parece ser puro. Uno puede escribir pruebas unitarias contra esto sin dificultad. Si se usa en otras clases, las pruebas unitarias aún se pueden escribir.
No es necesario abstraer las funciones sin dependencias, es excesivo.
Si esto se vuelve más complejo, tal vez se justifique pasar una interfaz a un constructor o método. Pero, no seguiría ese camino a menos que tuviera una
GetStringPart
lógica compleja basada en la ubicación, etc.fuente
Este es el por qué
Si hubiera seguido un método estático, no habría forma de cambiar el comportamiento
GetStringPart
sin destruir el comportamiento anterior o contaminarlo con lógica condicional. Es cierto que la estática es un malvado disfrazado, pero el hecho de que deshabilite el polimorfismo es mi principal queja sobre ellos. Los métodos estáticos no son de primera clase en lenguajes OOP. Al darle al método un objeto para vivir, incluso uno sin estado, hacemos que el método sea portátil. Su comportamiento se puede transmitir como el valor de una variable.Aquí he imaginado un sistema que debe comportarse de manera ligeramente diferente cuando se implementa en Europa que cuando se implementa en los EE. UU. En lugar de forzar a cualquiera de los sistemas a contener el código que solo necesita el otro, podemos cambiar el comportamiento controlando qué objeto de análisis de orden se inyecta en los clientes. Esto nos permite contener la difusión de los detalles de la región. También facilita agregar OrderParserCanada sin tener que tocar los analizadores existentes.
Si eso no significa nada para ti, entonces realmente no hay un buen argumento para esto.
Por cierto,
GetStringPart
es un nombre terrible.fuente
static getStringPartEU()
? Su ejemplo solo tiene sentido si hay otros métodos en esa clase que también requieren el tratamiento especializado de la UE y deben tratarse como una sola unidad.