Хотя я согласен с другими ответами, ОП спрашивал, почему бы не иметь класс со всеми статическими методами (возможно, со статическими полями) вместо синглтона, где у вас есть один экземпляр.
Зачем использовать синглтоны?
Вы можете Google "синглтон", чтобы найти все виды причин. От JavaWorld :
Иногда уместно иметь
ровно один экземпляр класса:
оконные менеджеры, диспетчеры очереди печати и
файловые системы являются прототипами.
Как правило, эти типы
объекты - известные как синглтоны -
доступ к разрозненным объектам
во всей системе программного обеспечения, и
поэтому требуют глобальной точки
доступ. Конечно, только когда ты
уверен, что вам никогда не понадобится больше, чем
один случай, это хорошая ставка, которую вы
передумать.
Зачем использовать Singleton вместо класса со всеми статическими методами?
Несколько причин
- Вы можете использовать наследование
- Вы можете использовать интерфейсы
- Упрощает выполнение модульного тестирования самого класса singleton
- Позволяет проводить модульное тестирование кода, который зависит от синглтона
Для # 3, если ваш Singleton был пулом соединения с базой данных, вы хотите убедиться, что у вашего приложения есть только один экземпляр, но выполнить модульное тестирование самого пула соединений с базой данных, не обращаясь к базе данных (возможно, с помощью области действия пакета). конструктор или статический метод создания):
public class DatabaseConnectionPool {
private static class SingletonHolder {
public static DatabaseConnectionPool instance = new DatabaseConnectionPool(
new MySqlStatementSupplier());
}
private final Supplier<Statement> statementSupplier;
private DatabaseConnectionPool(Supplier<Statement> statementSupplier) {
this.statementSupplier = statementSupplier;
}
/* Visibile for testing */
static DatabaseConnectionPool createInstanceForTest(Supplier<Statement> s) {
return new DatabaseConnectionPool(s);
}
public static DatabaseConnectionPool getInstance() {
return SingletonHolder.instance;
}
// more code here
}
(обратите внимание на использование держателя инициализации по требованию )
Затем можно выполнить тестирование DatabaseConnectionPool
с помощью метода package-scope createInstanceForTest
.
Обратите внимание, однако, что статический метод getInstance()
может вызвать «статическое цепление», когда код, который зависит от вашего синглтона, не может быть подвергнут модульному тестированию. Статические синглтоны часто не считаются хорошей практикой из-за этого (см. этот пост )
Вместо этого вы могли бы использовать инфраструктуру внедрения зависимостей, такую как Spring или Guice, чтобы гарантировать, что у вашего класса есть только один экземпляр в рабочей среде, при этом позволяя коду, который использует класс, быть тестируемым. Поскольку методы в Синглтоне не являются статичными, вы можете использовать макетную среду, такую как JMock, для моделирования вашего синглтона в тестах.