Принципы SOLID для тестировщиков: принцип инверсии зависимостей |
26.09.2024 00:00 |
Автор: Кристин Джеквони (Kristin Jackvony) Настало время для последнего принципа SOLID! Принцип инверсии зависимостей состоит из двух частей, и мы будем изучать их по одной. Во-первых, он гласит, что «Высокоуровневые модули должны зависеть не от низкоуровневых, а от абстракций». Чтобы с этим разобраться, надо понять разницу между «высокоуровневыми» и «низкоуровневыми" модулями. Низкоуровневый модуль отвечает за одну конкретную задачу – например, запрос к базе данных или отправка файла на печать. Для первого примера мы используем класс AddText, очищающий текстовое поле и вводящий туда новый текст.
Высокоуровневый модуль – это то, что отвечает за ключевую функциональность приложения или теста. Например, это может быть генерация отчета или создание нового пользователя. Для нашего примера мы воспользуемся классом UpdatePerson, обновляющий значение в соответствующей пользователю записи. class UpdatePerson { В этом примере мы обновляем запись, инициализируя класс AddText, затем инициализируя класс UpdatePerson, а затем – вызывая функцию обновления: const addText = new AddText() Однако этот пример нарушает принцип инверсии зависимостей! Класс UpdatePerson очень зависим от класса AddText. Если подпись (параметры и тип возвращаемого значения) функции clearAndEnterText изменится в классе AddText, придется также менять класс UpdatePerson. Обновим наш код, чтобы он соответствовал принципу. Вместо создания класса AddText создадим интерфейс AddText: interface AddText { Затем создадим класс PersonForm, внедряющий интерфейс. class PersonForm implements AddText { И, наконец, обновим класс UpdatePerson, чтобы он использовал PersonForm: class UpdatePerson { Теперь мы можем обновить значение, создавая копию класса PersonForm, а затем создавая и используя класс UpdatePerson: const userForm = new PersonForm() Теперь и класс PersonForm, и класс UpdatePerson зависят от интерфейса, а не от низкоуровневого модуля. Если подпись интерфейса clearAndEnterText изменится, нам нужно будет обновить PersonForm, но класс UpdatePerson в обновлении нуждаться не будет. Вторая часть принципа инверсии зависимостей гласит, что «абстракции не должны зависеть от деталей: детали должны зависеть от абстракций». Абстракция – это интерфейс или абстрактный класс, который определяет набор поведений, не уточняя детали реализации. И низкоуровневые, и высокоуровневые модули должны зависеть от абстракций, и если детали внедрения меняются, они не должны влиять на абстракцию. Иными словами, класс PersonForm может как угодно менять функцию clearAndEnterText, и это не затронет интерфейс AddText. К примеру, мы можем изменить класс PersonForm, чтобы он делал запись в лог, но на интерфейс AddText это никак не повлияет: class PersonForm implements AddText { Итак, я завершаю мою серию из пяти статей про принципы SOLID! Отдельная благодарность моей коллеге Монике Стэндифер, которая помогла мне лучше разобраться в принципах. Я, безусловно, многому научилась, и надеюсь, что вам помогут эти простые примеры, использующие распространенные методы! |