Вам когда-нибудь нужно уничтожить один экземпляр?

Используя одноэлемент, может быть создан только один экземпляр. Нужно ли нам когда-либо уничтожать этот экземпляр?

У меня есть singleton DBManager, который управляет JDBC-соединением и запросами. Вызывая его статический метод newInstance, я могу получить его экземпляр, затем я делаю некоторые запросы. Наконец, я хочу закрыть соединение с базой данных, и я вызываю другой статический метод, чтобы закрыть соединение JDBC.

Теперь соединение было закрыто, а экземпляр DBManager все еще жив, но не полезен. Нужно ли мне уничтожать его, например, присваивая ему значение null? В противном случае он может быть позже указан по ошибке.

Если я назначу этот экземпляр нулевым, то снова вызовите метод newInstance, я получу другой новый экземпляр?

Ответ 1

Я бы не стал зависеть от семантики "singleton" — ваше требование состоит в том, что в любой момент существует один экземпляр DBManager. Когда этот экземпляр окажется бесполезным, вы можете либо уничтожить его, чтобы создать новый экземпляр по запросу, либо определить ваш метод newInstance (который я мог бы предложить переименовать getInstance), чтобы исключить исключение (возможно, IllegalStateException), если он вызывается после того, как singleton был бесполезен.

Если вы собираетесь уничтожить его при бесполезности, я предлагаю, чтобы это было сделано внутри класса singleton автоматически, без внешней помощи. Вы также должны рассмотреть возможность полного скрытия singleton DBManager и реализации шаблона делегирования. Это позволит избежать проблемы с клиентом, сохраняющим ссылку на устаревший экземпляр DBManager. Затем вы можете сделать объект делегата регулярным синглом.

Ответ 2

Я бы сказал, что нет, вы не можете уничтожить синглтон, потому что он должен быть точно таким же, как и все его экземпляры. И, возможно, это должен быть тот же самый экземпляр, потому что в противном случае это не очень синглтон (например, два разных класса могут содержать ссылки на разные экземпляры класса).

Но, кстати, это одна из многих причин, почему я считаю, что одноэлементный шаблон практически не используется в реальном программном обеспечении. Вероятность того, что вы хотите, чтобы одна вещь, когда-либо, при любых обстоятельствах, до такой степени, что вы применяете это, не позволяя людям вызвать конструкторы, - слишком жестка. Это звучит как ситуация, когда в какой-то момент казалось разумным иметь одноэлемент, но теперь становится очевидным, что несколько экземпляров имеют смысл.

Итак, подумайте, должен ли это быть singleton - можете ли вы просто сделать его оболочкой вокруг соединения, которое было подключено по мере необходимости?

Ответ 3

Я думаю, что это будет больше соответствовать шаблону Singleton, чтобы заставить DBManager открывать и закрывать соединение без фактического уничтожения самого DBManager. Затем вы продолжите его до следующего подключения базы данных и попросите тот же объект DBManager создать новое соединение. В конце концов, если это DBManager, он управляет соединениями; он не представляет собой отдельное соединение.

Ответ 4

В таких случаях мы используем механизм объединения пулов. Каждая из ваших операций, запрашивающих базу данных , должна открывать и закрывать соединение. Однако, поскольку мы используем пул соединений, соединение возвращается в пул вместо физического закрытия.

В пуле под названием IDLE_CONNECTION_TIMEOUT или аналогичном будет установлен параметр, который автоматически истекает и закрывает соединения, если они не используются в течение настроенного периода времени. Так что, мало что нужно, чтобы разработчик беспокоился в таких случаях.

Ответ 5

Короткий ответ: No.

Дольше ответ: вы не можете уничтожить синглтон, за исключением использования специального Classloader. Если вам нужно уничтожить его, вы не должны использовать синглтон вообще. Возможно, вы можете переписать его таким образом, чтобы снова открыть его - лучше: избегайте одноэлементного рисунка.

Поиск анти-шаблона или запаха кода.

Ответ 6

Класс DBManager должен обрабатывать очистку, если соединение db закрыто. Если DBManager имеет ссылку на класс Connection, вы можете написать код в методе newInstance(), чтобы проверить, жив ли соединение, а затем вернуть static Reference. что-то вроде этого:

static DBManager manager;
static DBManager newInstance(){
if (manager == null) manager =new DBManager();
else if ( manager !=null && connection ==null) //if connection is closed 
manager =new DBManager();

return manager;
}

Ответ 7

Ответ должен быть не то, что вы не можете уничтожить синглтон, поскольку должны быть только один и один. Что касается вашей проблемы, у вас есть класс DBManager, соединение HASA, которое закрывается и становится бесполезным.

Я предполагаю, что ваша цель должна заключаться в том, чтобы одно подключение к базе данных было открыто в любой момент, поэтому я бы посмотрел на ваш код здесь, вы нарушаете принцип единой ответственности и гарантируете, что вы отделите ответственность за подключение к отдельный класс и разрешить вашей силе привилегию управлять своими соединениями - то есть закрывать и снова открывать ее по мере необходимости.

Ответ 8

Создайте геттер/сеттер для класса Variable и установите его yo null для повторного создания объекта Пример:

//Singleton support ...
private static A singleton = null;
    public static A get() {
        if (singleton == null){
        singleton = new A();
    }
        return singleton;
}
public static A getSingleton() {
    return singleton;
}
public static void setSingleton(A singleton) {
    A.singleton = singleton;
}

//Re instantiate 
public class Test(){
....
....
    A.setSingleton(null);

}