Если класс внутренне зависит от одного или нескольких ресурсов, и эти ресурсы влияют на поведение класса, то не следует использовать синглтон и статические утилитарные классы.
Классу не следует создавать эти ресурсы самостоятельно, вместо этого предпочтительнее передавать необходимые ресурсы в конструктор. Инъекция зависимостей позволяет улучшить гибкость, повторное использование и простоту тестирования класса.
Пример
Пример использования статического утилитарного класса
В данном утилитарном классе предполагается использование только одного словаря. Однако на практике словари могут быть разделены по языкам, а также могут существовать отдельные словари для специальной лексики.
Пример использования класса-синглтона
Класс-синглтон также предполагает использование только одного словаря, поэтому он имеет тот же недостаток, что и описанный выше.
Решение 1 - Удалить ключевое слово final из поля.
Можно также удалить ключевое слово final для поля dictionary в статическом утилитарном классе или классе-синглтоне и предоставить возможность извне заменить dictionary на другой словарь. Однако этот подход неудобен в использовании и может привести к проблемам с одновременностью в многопоточной среде.
Решение 2 - Использовать инъекцию зависимостей.
На примере выше видно, что статические классы и классы-синглтоны не должны зависеть от внутренних ресурсов. То есть, внутренние ресурсы предпочтительнее получать извне.
Класс с использованием инъекции зависимостей гарантирует неизменность благодаря ключевому слову final и поддерживает использование нескольких экземпляров ресурсов. Кроме того, инъекция зависимостей может применяться не только в конструкторе, но и в статических фабричных методах и билдерах.
Инъекция зависимостей может просто передавать сам ресурс, но часто используется и передача фабрики ресурсов. Фабрика — это объект, который при каждом вызове создаёт новый экземпляр определённого типа. Такой подход называется шаблоном «Фабричный метод», и Supplier<T> в Java 8 является прекрасным примером реализации фабрики.
Обычно для ограничения типа параметра фабрики используется ограниченный подстановочный знак. Это позволяет клиенту передавать в фабрику любой подтип указанного типа.
Инъекция зависимостей повышает гибкость и простоту тестирования, но в проектах с большим количеством зависимостей может быть весьма затратной. В таких случаях можно использовать фреймворки инъекции зависимостей (Dagger, Guice, Spring и др.), чтобы снизить затраты.
Источники
- Эффективная Java
- https://catsbi.oopy.io/d7f3a636-b613-453b-91c7-655d71fda2b1
Комментарии0