![translation](https://cdn.durumis.com/common/trans.png)
Это сообщение переведено AI.
Выбрать язык
Текст, резюмированный ИИ durumis
- Если класс внутренне зависит от одного или нескольких ресурсов, не рекомендуется использовать статические утилитарные классы и классы-синглтоны, вместо этого рекомендуется использовать инъекцию зависимостей.
- Использование инъекции зависимостей позволяет улучшить гибкость, повторное использование и тестируемость класса, а ресурсы можно ввести в конструктор, статический фабричный метод, строитель и т. д.
- Инъекция зависимостей может использоваться путем передачи самих ресурсов или ресурсов фабрики, а для проектов с большим количеством зависимостей эффективным решением является использование фреймворка зависимостей.
Если класс внутренне зависит от одного или нескольких ресурсов, и эти ресурсы влияют на работу класса, следует избегать использования синглтонов и статических утилитарных классов.
Класс не должен создавать эти ресурсы самостоятельно, а вместо этого лучше передавать необходимые ресурсы в конструктор. Инъекция зависимостей позволяет улучшить гибкость, возможность повторного использования и удобство тестирования класса.
Пример
Пример использования статического утилитарного класса
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Логика с использованием dictionary
}
public static List suggestions(String typo) {
// Логика с использованием dictionary
}
Предполагается, что этот утилитарный класс использует только один словарь. Однако в реальности словари могут быть разными для каждого языка, и даже могут быть отдельные словари для специальной лексики.
Пример использования класса-синглтона
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Логика с использованием dictionary
}
public static List suggestions(String typo) {
// Логика с использованием dictionary
}
Класс-синглтон также предполагает использование только одного словаря, поэтому возникает та же проблема, что и выше.
Решение 1 - Удалите ключевое слово final из поля.
public class SpellChecker {
private Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static void changeDictionary(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Логика с использованием dictionary
}
public static List suggestions(String typo) {
// Логика с использованием dictionary
}
Вы также можете удалить ключевое слово final для dictionary в статическом утилитарном классе или в классе-синглтоне и спроектировать его так, чтобы словарь можно было заменить на другой извне. Однако этот подход неудобен сам по себе и может привести к проблемам одновременности в многопоточной среде.
Решение 2 - Используйте инъекцию зависимостей.
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Логика с использованием dictionary
}
public static List suggestions(String typo) {
// Логика с использованием dictionary
}
Из приведенного выше примера видно, что статические классы и классы-синглтоны не должны зависеть от внутренних ресурсов. То есть, внутренние ресурсы должны поступать извне.
Класс, использующий инъекцию зависимостей, благодаря ключевому слову final гарантирует неизменяемость и поддерживает несколько экземпляров ресурсов. Кроме того, инъекция зависимостей может быть применена не только в конструкторе, но и в статических фабриках и строителях.
Инъекция зависимостей может быть реализована просто передачей самого ресурса, но часто используется также передача фабрики
ресурсов. Фабрика - это объект, который при вызове повторно создает экземпляр определенного типа. Такой подход называется шаблоном
фабричного метода, а Supplier
public static List create(Supplier extends Car> generator) {
...
Часто используется ограниченный подстановочный знак типа для ограничения типа параметра фабрики. Используя этот подход, клиент может передать любую фабрику, которая является подтипом объявленного типа.
Инъекция зависимостей улучшает гибкость и удобство тестирования, но в проектах с большим количеством зависимостей может быть достаточно дорогой. В таких случаях вы можете использовать фреймворки инъекции зависимостей (Dagger, Guice, Spring и т. д.) для сокращения затрат.
Источник
- Эффективная Java
- https://catsbi.oopy.io/d7f3a636-b613-453b-91c7-655d71fda2b1