what programming programación pelicula oriented orientada objetos oop

oop - programming - programación orientada a objetos



¿La inyección de dependencia rompe la Ley de Demeter? (7)

¿Cómo lo rompe? DI encaja perfectamente en la idea de menor conocimiento. DI le proporciona bajo acoplamiento: los objetos son menos acusados ​​entre sí.

Citando Wikipedia:

... un objeto A puede solicitar un servicio (llamar a un método) de una instancia de objeto B, pero el objeto A no puede "alcanzar" el objeto B para acceder a otro objeto ...

Por lo general, DI funciona exactamente de la misma manera, es decir, utiliza los servicios proporcionados por los componentes inyectados. Si su objeto intenta acceder a algunas de las dependencias de B, es decir, sabe mucho acerca de B, eso conduce a un alto acoplamiento y rompe la idea de DI

Sin embargo, estoy requiriendo que los objetos que están más arriba en mi cadena de llamadas tengan conocimiento de los objetos que se encuentran más abajo en la cadena de llamadas.

¿Algún ejemplo?

He estado agregando la inyección de dependencia a mi código porque hace que el código sea mucho más fácil para la prueba unitaria a través de la burla.

Sin embargo, estoy requiriendo que los objetos más altos en mi cadena de llamadas tengan conocimiento de los objetos que se encuentran más abajo en la cadena de llamadas.

¿Rompe esto la Ley de Demeter? Si es así, ¿qué importancia tiene?

por ejemplo: una clase A tiene una dependencia en una interfaz B, la implementación de esta interfaz para usar se inyecta en el constructor de clase A. Cualquiera que desee usar la clase A ahora también debe tener una referencia a una implementación de B. Y puede llamar a sus métodos directamente significado y tiene conocimiento de sus subcomponentes (interfaz B)

Wikipedia dice sobre la ley de Demeter: "La noción fundamental es que un objeto dado debe asumir lo menos posible sobre la estructura o las propiedades de cualquier otra cosa (incluidos sus subcomponentes)".


Inyección de Dependencia PUEDE romper la Ley de Demeter. Si fuerza a los consumidores a hacer la inyección de las dependencias. Esto se puede evitar mediante métodos de fábrica estáticos y marcos DI.

Puede tener ambos diseñando sus objetos de tal manera que requieran que se pasen las dependencias, y al mismo tiempo tener un mecanismo para usarlos sin realizar la inyección explícitamente (funciones de fábrica y marcos DI).


La Ley de Demeter especifica que el método M del objeto O puede llamar a métodos sobre objetos creados / instanciados dentro de M. Sin embargo, no hay nada que especifique cómo se crearon estos objetos. Creo que está perfectamente bien usar un objeto intermediario para crear estos, siempre y cuando el objetivo de ese objeto en la vida sea solo eso: crear otros objetos en su nombre. En este sentido, DI no infringe la Ley de Demeter.


Si lo entiendo correctamente, esto no es causado por el uso de la inyección de dependencia, sino que se debe al uso de estrategias de burla que hacen que especifique las llamadas de función que espera que haga un método. Eso es perfectamente aceptable en muchas situaciones, pero obviamente eso significa que debe saber algo sobre el método que está llamando, si ha especificado lo que cree que se supone que debe hacer.

Escribir un buen software requiere equilibrar las compensaciones. A medida que la implementación se vuelve más completa, se vuelve más inconsistente. Debe decidir qué riesgos crean esas incoherencias y si valen el valor creado por su presencia.


¿Viola la ley?
Estrictamente hablando, creo que sí.
¿Importa?
El principal peligro de violar la ley es que haces que tu código sea más frágil.
Si realmente lo mantienes solo en las pruebas, parece que el peligro no es tan malo.
Mitigación
Mi comprensión de la Ley de Demeter es que puede ser seguida por tener "métodos de envoltura" que impiden directamente llamar a objetos.


Depende :-)

Creo que la respuesta principal no es correcta, incluso con un marco de trabajo, una gran cantidad de código usa la inyección de Dependencia e inyecta objetos de alto nivel. A continuación, obtiene el código de spaghetti con muchas dependencias.

La inyección de dependencia se utiliza mejor para todas las cosas que podrían contaminar su modelo de objeto, por ejemplo, un ILogger. Si inyectas un objeto comercial, asegúrate de que esté en el nivel más bajo posible e intenta pasar el método tradicional si puedes. Solo usa la inyección de dependencia si se vuelve desordenada.


Antes de agregar mi respuesta, debo calificarla. La Programación Orientada a Servicios se basa en los Principios OOP y el uso de OO Languages. Además, las SOA siguen la Inversión de Control y los Principios SÓLIDOS en los dientes. Así que muchos programadores orientados al servicio seguramente están llegando aquí. Entonces, esta respuesta es para los programadores orientados al servicio que llegan a esta pregunta, porque SOA se basa en OOP. Esto no responde directamente el ejemplo del PO, pero responde la pregunta desde una Perspectiva SOA.

En general, la Ley de Demeter no se aplica a Arquitecturas Orientadas a Servicios. Para OO, la Ley de Demeter está hablando de "objetos ricos" en OOP que tienen propiedades y métodos, y cuyas propiedades también pueden tener métodos. Con OOP Rich Models, es posible acceder a través de una cadena de objetos y métodos de acceso, propiedades, métodos de propiedades, métodos de propiedades, etc. Pero en Programación Orientada a Servicios, los Datos (Propiedades) están separados del Proceso (Métodos ) Sus Modelos (principalmente) solo tienen propiedades (Ciertamente nunca dependencias), y sus Servicios solo tienen Métodos y dependencias en otros Servicios.

En SOP, puede tener la libertad de revisar las propiedades de un modelo y las propiedades de sus propiedades. Nunca podrá acceder a métodos que no debería, solo un árbol de datos. Pero, ¿qué pasa con los Servicios? ¿La Ley de Demeter se aplica allí?

Sí, la Ley de Demeter se puede aplicar a los servicios de SOP. Pero, nuevamente, la ley fue originalmente diseñada para modelos ricos en OOP. Y a pesar de que la ley se puede aplicar a los servicios, la inyección de dependencia adecuada cumple automágicamente la Ley de Demeter. En ese sentido, DI no podría violar la ley.

En oposición limitada a Mark Roddy, no puedo encontrar ninguna situación en la que legítimamente se pueda hablar de Dependency Injection y de "consumidores" en la misma oración. Si por "consumidores" te refieres a una clase que está consumiendo otra clase, eso no tiene sentido. Con DI, tendría una raíz de composición que componga su gráfico de objetos, y una clase nunca debería saber que existe otra clase. Si por "consumidores" te refieres a un programador, ¿cómo no se los forzaría a "hacer la inyección"? El programador es el que tiene que crear la raíz de composición, por lo que debe hacer la inyección. Un programador nunca debe "hacer la inyección" como una instanciación dentro de una clase para consumir otra clase.

Revise el siguiente ejemplo que muestra soluciones separadas reales, sus referencias y el código de implementación:

En la esquina superior derecha, tenemos el "Núcleo". Muchos paquetes en NuGet y NPM tienen un proyecto "Core" que tiene Model, Interfaces y posiblemente incluso implementaciones predeterminadas. El Núcleo nunca debería depender nunca de algo externo.

En la parte superior izquierda, tenemos una implementación externa del Core. La implementación depende del Núcleo, y también lo tiene conocimiento.

En la esquina inferior izquierda, tenemos un dominio independiente. El dominio tiene una dependencia en alguna implementación del núcleo, pero no necesita saber sobre la implementación .

Aquí es donde señalo que ni el Dominio ni la Implementación se conocen. Hay un 0% de posibilidades de que cualquiera llegue a (o más allá) del otro, porque ni siquiera saben que existen. El dominio solo sabe que hay un contrato, y de alguna manera puede consumir los métodos por lo que sea que se inyecte en él.

En la esquina inferior izquierda está la raíz de composición o el punto de entrada. Esto también se conoce como el "límite frontal" de la aplicación. La raíz de una aplicación conoce todos sus componentes y hace poco más que tomar entrada, determinar a quién llamar, componer objetos y devolver resultados. En otras palabras, solo puede decirle al dominio "Aquí, usa esto para cumplir tu contrato de ICalculateThings, luego dame el resultado de CalculateTwoThings.

De hecho, hay una forma de destruir todo en el mismo proyecto, hacer instancias concretas de Servicios, hacer que sus dependencias sean propiedades públicas en lugar de campos privados, STILL Do Dependency-Injection (horriblemente) y luego hacer que los servicios invoquen dependencias de dependencias. Pero eso sería malo, m''kay. Tendría que estar tratando de ser malo para hacer eso.

Nota al margen, lo sobre compliqué a propósito. Estos proyectos podrían existir en una sola solución (siempre que el Arquitecto controle la Arquitectura de Referencia), y podría haber algunas simplificaciones más. Pero la separación en la imagen realmente muestra cuán poco conocimiento tiene el sistema sobre sus partes. Solo la raíz de composición (punto de entrada, límite frontal) necesita conocer las partes.

Conclusión (TL; DR;): En Oldskewl OOP, los Modelos son Ricos, y la Ley de Demeter se puede romper fácilmente buscando modelos de modelos para acceder a sus métodos. Pero en Newskewl SOP (construido sobre Principios e idiomas de OOP), los datos se separan del proceso. Así que puede sentirse libre de examinar las propiedades de los modelos. Luego, para los Servicios, las dependencias son siempre privadas, y nada sabe que exista algo más aparte de lo que les dicen las abstracciones, los contratos, las interfaces.