О принципе инверсии зависимостей (DIP) в этой статье, это будет последняя статья о SOLID.

Сегодня я продолжу рассказывать о принципе инверсии зависимостей (DIP) в этой статье. Мы будем знакомы с другими принципами в SOLID, потому что даже если мы не знаем о >ПРОВЕРЕННЫЙпринцип, который мы можем изучить из кода нашего старшего специалиста, различных средних статей и учебных пособий, но вы очень редко услышите, что такое инверсия зависимостей и как мы должны ее использовать и почему мы должны использовать.

Кстати, если вы уже работаете Android-разработчиком, не путайте с внедрением зависимостей. Вы уже знакомы с популярными библиотеками Dagger, Hilt и Koin. Эти двое очень разные, поэтому будьте осторожны, когда вы объясняете, особенно в интервью.

Внедрение зависимостей – это метод реализации для заполнения переменных экземпляра класса. Инверсия зависимостей — это общее руководство по проектированию, в котором рекомендуется, чтобы классы имели прямые отношения только с высокоуровневыми абстракциями.

Принцип инверсии зависимостей (DIP): модули высокого уровня не должны зависеть от модулей низкого уровня; оба должны зависеть от абстракций.

Позвольте мне объяснить вам простую реализацию кода, после чего вы лучше поймете DIP. Как обычно, начнем с класса Student, который зависит от класса Teacher для выполнения некоторых функций:

class Student(private val teacher: Teacher) {
    fun askQuestion(question: String) {
        teacher.answerQuestion(question)
    }
}

В приведенном выше примере класс Student напрямую зависит от класса Teacher, что нарушает DIP, поскольку модуль высокого уровня (Student) зависит от модуля низкого уровня (Teacher). .

поэтому пусть рефакторинг придерживается DIP, мы можем ввести абстракцию между классами Student и Teacher:

interface QuestionAnswerer {
    fun answerQuestion(question: String)
}

class Teacher : QuestionAnswerer {
    override fun answerQuestion(question: String) {
        // answer the specified question
    }
}

class Student(private val questionAnswerer: QuestionAnswerer) {
    fun askQuestion(question: String) {
        questionAnswerer.answerQuestion(question)
    }
}

В этой рефакторинговой версии мы вводим абстракцию под названием QuestionAnswerer, от которой зависит класс Student, а не напрямую класс Teacher. Класс Teacher реализует интерфейс QuestionAnswerer, а класс Student теперь зависит от интерфейса, а не от конкретного класса Teacher.

Это соответствует DIP, потому что класс Student теперь зависит от абстракции (QuestionAnswerer), а не от конкретной реализации (Teacher). Это обеспечивает большую гибкость и расширяемость, поскольку любой класс, реализующий интерфейс QuestionAnswerer, может использоваться в качестве зависимости для класса Student, а не только для класса Teacher.

Увидев рефакторинговую версию, я надеюсь, вы поймете, почему мы также должны использовать Dependency Inversion, DIP помогает разделить компоненты в вашем приложении и может сделать ваш код более гибким, удобным в сопровождении и более простым для тестирования.

Спасибо, что нашли время прочитать эту статью. Я надеюсь, что мое письмо было информативным и наводящим на размышления. Удачного кодирования для всех вас, чем раньше.

Предыдущая статья о SOLID:

Принцип единой ответственности (SRP): https://medium.com/arpalar-tech/solid-from-zero-to-potato-e7b5cfe8c7a1

Открытый/закрытый принцип (OCP): https://medium.com/arpalar-tech/solid-from-zero-to-potato-2-5a4c17bd8ec8

Принцип замещения Лисков (LSP): https://medium.com/arpalar-tech/solid-from-zero-to-potato-3-94d6f63dbbfe

Принцип разделения интерфейса (ISP): https://medium.com/arpalar-tech/solid-from-zero-to-potato-4-d1d9b42c3a78