¿Debería el uso de la inyección de dependencia y un contenedor de inversión de control eliminar todas las apariciones de la new
palabra clave " " de su código?
En otras palabras, ¿debería cada objeto / dependencia, sin importar cuán simple o de corta duración, ser "registrado" dentro de su contenedor IoC e inyectado en el método / clase que necesita usarlos?
Si no, ¿dónde dibuja la línea entre las dependencias / objetos que se registran en el contenedor IoC, frente a lo que se crea "en línea" como referencia concreta, a través de la new
palabra clave?
.net
dependency-injection
ioc-containers
CraigTP
fuente
fuente
Respuestas:
Evita el dogma. Haz lo que se siente bien.
Prefiero usar "nuevo" para estructuras de datos que no tienen comportamiento.
Si la clase tiene comportamiento, entonces miro el alcance de ese comportamiento. Si no tiene estado y no tiene dependencias, me inclino hacia "nuevo". Solo comienzo a refactorizar hacia DI cuando necesito agregar una dependencia a recursos con estado (como una base de datos o un archivo), o a otras clases con tales recursos.
fuente
new
dependencia ed en mi propio código que provocó mi pregunta. Era una clase simple sin funcionalidad o "comportamiento" per se, solo propiedades simples.En mi libro , presento la distinción entre dependencias estables y volátiles . Es muy importante usar DI con dependencias volátiles, pero a menudo puede lograr un acoplamiento aún más suelto al abstraer e inyectar dependencias estables.
Tenga en cuenta que la aplicación de DI no debe depender de un contenedor DI . En el caso de que se use la DI de Poor Man , no
new
se eliminan las palabras clave, solo se mueven a la raíz de composición .Algunas personas prefieren la DI de Poor Man a los contenedores de DI. El costo de mantenimiento puede ser mayor, pero a cambio obtienes seguridad en tiempo de compilación. Como escuché recientemente a Dan North decir: "
new
es lo nuevonew
" :)Lo que se quiere decir con esto es simplemente que, en lugar de implementar la raíz de composición con un contenedor DI, solo contendría un montón de
new
declaraciones anidadas .fuente
"nuevo" no es una palabra clave prohibida. Mis reglas personales:
Todos los "servicios" (llamo a un servicio una clase diseñada para proporcionar uno o más métodos relacionados con una y solo una cosa; por ejemplo: acceder a la base de datos, recuperar / actualizar datos relacionados con un dominio dado) están registrados en el contenedor de COI. Ninguna clase debería tomar la decisión sobre cómo obtener la implementación de un servicio dado que necesita usar. Por lo tanto, siempre que necesite utilizar un servicio existente, debe configurar su clase y el contenedor IOC para que se lo proporcione. Imagine que no sabe cómo funciona su implementación, podría ser un servicio web, no le importa.
Todos los beans o modelos deben crearse con la palabra clave "nueva" o con una fábrica registrada por el COI cuando necesito que tengan algunas propiedades predeterminadas habilitadas. También está el caso particular de las clases de utilidad que contienen solo métodos estáticos (por ejemplo: un servicio de utilidad matemático). Si son totalmente independientes y no necesitan ninguna conexión a la base de datos u otro servicio registrado por el COI, los dejo fuera del COI y se los llamará estáticamente. Sin embargo, si una de esas clases necesita usar un servicio registrado con IOC existente, lo cambio a una clase singleton y lo registro en el IOC.
fuente
Solo me gustaría agregar a las respuestas existentes que se mencionaron anteriormente,
new
está perfectamente bien crear objetos que sean objetos de valor puro (es decir, que solo tengan propiedades / captadores / establecedores). Vea el Blog de Google Testing para más detalles.fuente
new
'edClaramente depende del idioma que uses. Si su lenguaje lo obliga a usar objetos para representar tanto el objeto real como los registros (objeto de valor, estructuras), entonces la respuesta es probablemente no.
Hablando exclusivamente de objetos "reales", no hay nada de malo en crear una instancia explícitamente. Sin embargo, debe tener en cuenta que todas las clases deben seguir el principio de responsabilidad única. No debería ser responsabilidad de una clase elegir el implementador de un servicio en el que se basa. Sin embargo, hay clases que tienen esa responsabilidad, es decir, proporcionar implementadores de ciertos servicios. Un IoC podría ser tal clase. De hecho, cualquier tipo de fábrica es tal clase.
Para resumir: solo esas clases deberían instanciar objetos directamente, quién es la responsabilidad de elegir qué clases instanciar.
Puede encontrar útiles estos criterios: http://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Creator
fuente
Una palabra: no.
Más palabras: la inyección de dependencia es exactamente eso. Es un medio por el cual introduce recursos de los que depende otro objeto, pero no debe conocer los detalles intrincados de otra fuente. Usar DI no significa que NADA en su programa deba saber cómo crear cualquier otro objeto; de hecho, considero que es altamente inviable que un programa no trivial evite por completo la "nueva" palabra clave (o alternativas basadas en la reflexión). Sin embargo, DI significa que los objetos que no deberían TENER que saber cómo crear objetos complejos que requieren muchas dependencias que acoplarán estrechamente este objeto con el otro, no deberían tener todo este conocimiento estrechamente acoplado.
Estudiaría las dos principales teorías del diseño de software de O / O, GRASP y SOLID. GRASP le dirá que estudie el propósito del objeto y se preguntará: "¿Debería este objeto ser responsable de crear nuevos objetos de este otro tipo? ¿Es eso parte de la 'descripción del trabajo' de este objeto?" SOLID va un paso más allá: la "S" representa el "Principio de responsabilidad única", que establece inequívocamente que un objeto debe tener un trabajo, y debe ser el único objeto en el programa que hace ese trabajo específico.
Por lo tanto, GRASP generalmente lo alentaría a que revise sus clases existentes para las que crea estos nuevos objetos, y encuentre uno para el cual la tarea de crear este objeto se ajuste a lo que el objeto ya hace, mientras mantiene el nivel deseado de "cohesión". SOLID le dirá que la cohesión es clave; La tarea de crear estos objetos debe asignarse a alguna fábrica que debe inyectarse en su clase. Creo que descubrirá, a medida que la complejidad de su programa continúa creciendo, que el cumplimiento de cualquiera de estas metodologías, con la voluntad de refactorizar, dará como resultado arquitecturas muy similares.
fuente