О принципе инверсии зависимостей (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