Разница между этими двумя принципами для меня не ясна. Они просто похожи на одно и то же.Разница между «зависит от абстракций не конкретных классов» и «от программы к интерфейсу»
Какая разница, если таковая имеется?
Разница между этими двумя принципами для меня не ясна. Они просто похожи на одно и то же.Разница между «зависит от абстракций не конкретных классов» и «от программы к интерфейсу»
Какая разница, если таковая имеется?
Из Patterns книги Head First Design, стр 139, касающийся "Dependency Inversion" принцип:
принцип инверсии зависимостей: Зависят от абстракций. Не зависит от конкретных классов.
Во-первых, этот принцип очень похож на «программу на интерфейс, а не на реализацию», правильно? Это похоже; однако принцип инверсии зависимостей делает еще более сильное утверждение об абстракции. Это предполагает, что наши компоненты высокого уровня не должны зависеть от наших низкоуровневых компонентов; скорее, они должны и зависят от абстракций.
«Высокоуровневый» компонент - это класс с поведением, определенным в терминах других компонентов «низкого уровня». Например,
PizzaStore
является компонентом высокого уровня, потому что его поведение определяется с точки зрения пиццы - оно создает все различные объекты пиццы, готовит, печет, разрезает и помещает их в кавычки, в то время как пицца, которую он использует, представляет собой низкоуровневые компоненты.
Следующий код следует «программу на интерфейс, а не реализация» принципа, потому что вы звоните Bake
и Deliver
на абстракции. Но это не следовать принципу DI, потому что ваш первый блок кода все еще зависит от некоторых конкретных типов Pizza
.
public class PizzaStore
{
public void OrderPizza(PizzaType type)
{
Pizza pizza;
switch(type)
{
case PizzaType.FourSeasons:
pizza = new FourSeasonsPizza();
//...
}
//do something with pizza
pizza.Bake();
pizza.Deliver();
}
}
С помощью шаблона метода фабрики, или абстрактной модели фабрики, вы следуете как принципы. Теперь вы программируете против абстракции и, вы зависите только от абстракций. Магазин пиццы зависит от двух абстракций: Pizza
и PizzaFactory
.
public class PizzaStore
{
private PizzaFactory factory;
public PizzaStore(PizzaFactory factory)
{
this.factory = factory;
}
public void OrderPizza(PizzaType type)
{
Pizza pizza = factory.CreatePizza(type);
//do something with pizza
pizza.Bake();
pizza.Deliver();
}
}
Да, принцип DI включает принцип «программа для интерфейса».
В книге GoF Patterns вы можете найти определение «интерфейс». Набор всех сигнатур, определенных операциями объекта, называется интерфейсом к объекту. Интерфейсы в этой книге были объявлены в .h файлах и отделены от реализации. Итак, данные принципы являются синонимами.
Разработчики .NET, не знакомые с книгой GoF Patterns, могут быть смущены .NET interfaces.
Ну, именно эта книга привела к этому вопросу, поскольку он вводит эти два отдельных принципа как нечто иное, но объяснения для меня недостаточно. В лучшем случае я могу видеть, что «программа для интерфейса» уже включена в «зависимость от абстракций», которую я вижу как просто высказывание «стремиться к свободной связи» разными словами. –
@LeNoob Я обновил свой пост, надеюсь, что теперь это яснее. Я согласен с вами в том, что принцип DI включает в себя * программирование на интерфейс *. – dcastro