Например, если у класса A есть зависимость от класса B, рефакторинг ее с помощью инверсии зависимостей приведет к классу A в зависимости от интерфейса B, который реализуется классом B.
- До рефакторинга: Класс A ---> Класс B
- После рефакторинга: Класс A ---> Интерфейс B <--- Класс B </li>
В двух словах, принцип инверсии зависимостей гласит, что как ваши абстракции высокого уровня (например, класс A), так и ваши абстракции низкого уровня (например, класс B) не должны зависеть от чего-то конкретного ( так как класс A зависел от класса B до рефакторинга), но был отделен средним абстрактным слоем (абстракция интерфейса B).
Инверсия зависимостей используется как средство реализации внедрения зависимостей. Например, весной
interface AbstractB {
}
@Component
class ConcreteB implements AbstractB {
}
@Component
class ConcreteA {
@Autowired
// note reference type is AbstractB
private AbstractB concreteB;
}
- В зависимости от ссылки типа AbstractB (вместо ConcreteB) в ConcreteA мы применяем инверсию зависимостей .
- Используя @Autowired и позволяя Spring внедрить эту зависимость для нас (вместо того, чтобы создавать ее самостоятельно с помощью ключевого слова 'new'), мы используем внедрение зависимостей .
- Инверсия управления - это принцип, позволяющий внешней структуре (в данном примере, контейнеру Spring IoC) создавать ваши зависимости и вставлять их в ваш код.
Относительно «Достигаем ли мы МОК, используя также DIP?», На мой взгляд, не обязательно, так как мы могли бы автоматически подключаться с эталоном типа ConcreteB, достигая IoC и DI, но нарушая DIP.
Это отвечает на ваш вопрос?