Есть ли причина хранить ссылку на экземпляр Singleton в другом классе в Java? - PullRequest
3 голосов
/ 24 августа 2011

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

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

Небольшой пример кода для иллюстрации:

enum SomeSingletonObject {
    INSTANCE;

    public void someMethod() {...}
}

class AnotherObject {
    private SomeSingletonObject sso;

    public AnotherObject() {
        this.sso = SomeSingletonObject.INSTANCE;
    }

    public void someMethod() {
        sso.someMethod();
        // instead of 
        // SomeSingletonObject.INSTANCE.someMethod();
    }
}

Ответы [ 4 ]

7 голосов
/ 24 августа 2011

В этом примере нет никакой выгоды.

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

1 голос
/ 24 августа 2011

Первая причина, которая приходит на ум, - это облегчить замену другим объектом, который реализует общий интерфейс или расширяет общий суперкласс.

Кроме того, возможно, что существуют два экземпляра синглтона, если они загружены разными загрузчиками классов.

Кроме того, хотя и не совсем в духе шаблона singleton, его можно использовать для хранения ссылки на старый экземпляр объекта singleton.

0 голосов
/ 24 августа 2011

Если вы можете гарантировать, что данный синглтон действительно является синглтоном , этот подход будет работать.В более сложной среде это может дать сбой, например:

public class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton instance() {

        if (someCondition == true) {
            Singleton.instance.close() // close the object
            Singleton.instance = new Singleton();
        }

        return Singleton.instance;
    }
}

Приведенный выше пример не является единичным, но он нарушит код, который вы указали, поскольку новая ссылка была присвоена instance.Эти проблемы могут возникнуть, если вы используете внешние библиотеки без понимания / доступа к их внутреннему поведению.

Я бы избегал "кэширования" ссылки на одиночный файл.

0 голосов
/ 24 августа 2011

На самом деле мне может показаться, что в этом есть некоторое преимущество: если вы используете enum с конструктором для управления статической ссылкой, он будет инициализирован при запуске (как при загрузке класса) и никогда не сможет измениться после этого.

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

С отрицательной стороны вы можете потерять управление жизненным циклом статической ссылки, если enum выполняет инициализацию.

Лучшее решение состоит в том, чтобыкак правило, избегайте статических синглетов, подобных этому, и полагайтесь на внедрение зависимостей или AOP (@Configurable от Google Spring).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...