«Программа для интерфейса» означает, что не зависит от конкретного типа для выполнения вашей работы , но он не определяет, как вы должны получить свою зависимость.
«Принцип инверсии зависимостей» говорит, что объект не должен контролировать создание своих зависимостей, он должен просто объявлять, какая зависимость ему нужна, и позволить вызывающей стороне предоставить ее . Но это не указывает, должна ли зависимость быть конкретным типом или интерфейсом.
Я проиллюстрирую различия с помощью некоторого кода на C #.
Следующий пример зависит от конкретного типа и управляет созданием собственной зависимости. Это не следует ни за «программой к интерфейсу», ни «инверсией зависимостей»:
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor()
{
_myThing = new MyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
Следующий пример зависит от интерфейса, но он контролирует создание собственной зависимости. Это следует за «программой к интерфейсу», но не «инверсией зависимости»:
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor()
{
_myThing = ThingFactory.GiveMeANewMyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
Следующий пример зависит от конкретного типа, но запрашивает, чтобы его зависимость была создана и передана ему. Это следует за "инверсией зависимости", но не "программой к интерфейсу":
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor(MyThing myThing)
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}
Следующий пример зависит от интерфейса и запрашивает, чтобы его зависимость была создана и передана ему. Это следует за "инверсией зависимости" и "программой к интерфейсу":
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor(IMyThing myThing) // using an interface
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}
PrintStream
должен зависеть от интерфейса, установленногоByteOutputStream
. Внедрение зависимости ничего не говорит о том, кто должен зависеть от кого.Они вообще одно и то же. Если вы читаете, что такое принцип обращения зависимостей и почему он важен? и Принцип инверсии зависимости , вы поймете, что два «принципа» говорят в основном об одном и том же.
Интерфейс - это абстракция, а реализация - это деталь. Если вы замените их в предыдущих двух утверждениях, вы получите «код должен зависеть от интерфейсов, а не от реализаций». И это звучит как то же самое для меня.
источник
Интерфейсы являются одним из способов реализации DI. Если вы указали интерфейс в качестве параметра в методе конструктора класса, вы можете передать любой понравившийся объект этому методу конструктора, если этот объект реализует интерфейс параметра конструктора.
Другими словами, программирование интерфейса позволяет изменить реализацию этого интерфейса. Это то, как мы можем заменить фиктивные объекты реальными объектами во время модульного тестирования, указать разных поставщиков данных и так далее.
источник