Это могло бы походить на странную идею, и я правильно еще не продумал ее.
Скажите, что у Вас есть приложение, которое заканчивает тем, что требовало, чтобы определенное число одиночных элементов сделало некоторый ввод-вывод, например. Вы могли записать один одиночный элемент и в основном воспроизвести код как много раз по мере необходимости.
Однако как программисты мы, как предполагается, предлагаем изобретательные решения, которые избегают дублирования или повторения любого вида. Что было бы решением сделать несколько somethings, которые могли каждый действовать как одиночный элемент.
P.S.: Это для проекта, где платформа, такая как Spring не может использоваться.
Вы можете ввести абстракцию следующим образом:
public abstract class Singleton<T> {
private T object;
public synchronized T get() {
if (object == null) {
object = create();
}
return object;
}
protected abstract T create();
}
Тогда для каждого синглтона достаточно написать следующее:
public final Singleton<Database> database = new Singleton<Database>() {
@Override
protected Database create() {
// connect to the database, return the Database instance
}
};
public final Singleton<LogCluster> logs = new Singleton<LogCluster>() {
...
Затем вы можете использовать синглтоны, написав database.get()
. Если синглтон не был создан, он создается и инициализируется.
Причина, по которой люди, вероятно, не делают этого и предпочитают просто многократно писать что-то вроде этого:
private Database database;
public synchronized Database getDatabase() {
if (database == null) {
// connect to the database, assign the database field
}
return database;
}
private LogCluster logs;
public synchronized LogCluster getLogs() {
...
заключается в том, что в конечном итоге это всего лишь еще одна строка кода для каждого синглтона, и шанс ошибиться в шаблоне инициализации синглтона довольно низок.
Однако, как программисты, мы должны придумывать изобретательные решения, которые избегают избыточности или повторений любого рода.
Это неверно. Как программисты, мы должны придумывать решения, которые отвечают следующим критериям:
(Эти критерии примерно упорядочены по убыванию приоритета, хотя различные контексты могут диктовать другой порядок.)
Изобретательность НЕ является требованием, и "избегать избыточности или повторений любого рода" тоже не является. На самом деле оба эти требования могут быть явно вредными... если программист игнорирует реальные критерии.
Возвращаясь к вашему вопросу. Вы должны искать альтернативные способы делать синглтоны, только если это действительно сделает код более удобным для сопровождения. Сложные "изобретательские" решения вполне могут вернуться, чтобы укусить вас (или людей, которым придется поддерживать ваш код в будущем), даже если им удастся сократить количество строк повторяющегося кода.
И, как отмечали другие (например, @BalusC), текущее мнение таково, что паттерн singleton следует избегать во многих классах приложений.
@BalusC прав, но я скажу это сильнее, синглтоны - зло во всех контекстах. Веб-приложения, настольные приложения и т. Д. Просто не делайте этого.
Все, что представляет собой синглтон, на самом деле - это глобальный пакет данных. Глобальные данные плохие. Это делает невозможным правильное модульное тестирование. Это значительно усложняет отслеживание странных ошибок.
Книга «Банда четырех» здесь совершенно неверна. Или, по крайней мере, устарели на полтора десятилетия.
Если вам нужен только один экземпляр, имейте фабрику, которая производит только один. Это просто.
Действительно существует многотоновый шаблон. Независимо от этого, я на 60% уверен, что реальным решением исходной проблемы является РСУБД.
Как насчет передачи параметра функции, которая создает синглтон (например, его имя или специализацию), которая знает, как создать синглтон для каждого уникального параметра?
Я знаю, что вы спросили о Java, но вот решение в PHP в качестве примера:
abstract class Singleton
{
protected function __construct()
{
}
final public static function getInstance()
{
static $instances = array();
$calledClass = get_called_class();
if (!isset($instances[$calledClass]))
{
$instances[$calledClass] = new $calledClass();
}
return $instances[$calledClass];
}
final private function __clone()
{
}
}
Тогда вы просто пишете:
class Database extends Singleton {}