Principio de inversión de dependencia vs "Programa para una interfaz, no una implementación"
12
Estoy tratando de entender cómo el principio de inversión de dependencia difiere del principio de "programa a interfaz, no de implementación".
Entiendo lo que significa "Programa para una interfaz, no una implementación". También entiendo cómo permite diseños más flexibles y fáciles de mantener.
Pero no entiendo cómo el Principio de Inversión de Dependencia es diferente del principio "Programa a una interfaz, no una implementación".
Leí acerca de DIP en varios lugares en la web, y no aclaró mi confusión. Todavía no veo cómo los dos principios difieren entre sí. Gracias por tu ayuda.
"Programar a una interfaz" significa no depender de un tipo concreto para hacer su trabajo , pero no especifica cómo debe obtener su dependencia.
El "Principio de inversión de dependencia" dice que un objeto no debe controlar la creación de sus dependencias, solo debe anunciar qué dependencia necesita y dejar que la persona que lo llama se la proporcione . Pero no especifica si la dependencia debe ser un tipo concreto o una interfaz.
Ilustraré las diferencias con un código C #.
El siguiente ejemplo depende de un tipo concreto y controla la creación de su propia dependencia. No sigue ni "programa a una interfaz" ni "inversión de dependencia":
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor()
{
_myThing = new MyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
El siguiente ejemplo depende de una interfaz, pero controla la creación de su propia dependencia. Sigue "programa a una interfaz", pero no "inversión de dependencia":
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor()
{
_myThing = ThingFactory.GiveMeANewMyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
El siguiente ejemplo depende de un tipo concreto, pero pide que se cree y se le pase su dependencia. Sigue "inversión de dependencia", pero no "programa a una interfaz":
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor(MyThing myThing)
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}
El siguiente ejemplo depende de una interfaz y solicita que se cree y se le pase su dependencia. Sigue tanto "inversión de dependencia" como "programa para una interfaz":
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor(IMyThing myThing) // using an interface
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}
De lo que estás hablando es de una inyección dependiente. Y la inversión de dependencia y la inyección de dependencia son dos cosas diferentes.
Eufórico
1
@Euphoric Estoy hablando del principio de inversión de dependencia, que es un concepto abstracto, al usar la inyección de dependencia como ejemplo de implementación concreta. Entiendo la diferencia.
Eric King
1
@EricKing Entonces deberías decir explícitamente eso en tu respuesta en lugar de decir "El" Principio de Inversión de Dependencia "dice ...", lo cual obviamente es incorrecto si lees mi respuesta.
Eufórico
1
Estoy de acuerdo con Euphoric. El Principio de Inversión de Dependencia dice que las capas de código de nivel superior deberían depender de fragmentos de código de nivel inferior, no al revés. Por ejemplo, PrintStreamdebe depender de la interfaz establecida por ByteOutputStream. La inyección de dependencia no menciona nada sobre quién debería depender de quién.
Los módulos de alto nivel no deberían depender de los módulos de bajo nivel. Ambos deberían depender de abstracciones.
Las abstracciones nunca deberían depender de los detalles. Los detalles deben depender de las abstracciones.
La interfaz es una abstracción y la implementación es un detalle. Si los sustituye en las dos declaraciones anteriores, obtendrá básicamente "el código debe depender de las interfaces y no de las implementaciones". Y eso me suena igual.
Esta debería ser la respuesta aceptada, la otra respuesta más votada es engañosa
Sameh Deabes
2
Las interfaces son una forma de implementar DI. Si especifica una interfaz como parámetro en el método constructor de una clase, puede entregar cualquier objeto que desee a ese método constructor, siempre que ese objeto implemente la interfaz del parámetro constructor.
En otras palabras, programar una interfaz le permite cambiar la implementación de esa interfaz. Es cómo podemos sustituir objetos simulados por objetos reales durante las pruebas unitarias, especificar diferentes proveedores de datos, etc.
PrintStream
debe depender de la interfaz establecida porByteOutputStream
. La inyección de dependencia no menciona nada sobre quién debería depender de quién.Generalmente son lo mismo. Si lees ¿Cuál es el principio de inversión de dependencia y por qué es importante? y el Principio de inversión de dependencia , se dará cuenta de que los dos "principios" hablan básicamente de lo mismo.
La interfaz es una abstracción y la implementación es un detalle. Si los sustituye en las dos declaraciones anteriores, obtendrá básicamente "el código debe depender de las interfaces y no de las implementaciones". Y eso me suena igual.
fuente
Las interfaces son una forma de implementar DI. Si especifica una interfaz como parámetro en el método constructor de una clase, puede entregar cualquier objeto que desee a ese método constructor, siempre que ese objeto implemente la interfaz del parámetro constructor.
En otras palabras, programar una interfaz le permite cambiar la implementación de esa interfaz. Es cómo podemos sustituir objetos simulados por objetos reales durante las pruebas unitarias, especificar diferentes proveedores de datos, etc.
fuente