Когда мы должны пойти на класс Singleton в Java? - PullRequest
6 голосов
/ 26 августа 2011

В соответствии с моими мыслями, мы должны создать класс как Singleton, когда мы совместно используем одно и то же состояние объекта в приложении.В этом случае мы хотим, чтобы пользователь каждый раз ограничивал создание нового экземпляра, чтобы он не мог поддерживать несколько состояний.Согласовано.Но такое же поведение можно добиться, объявив переменные экземпляра как статические.Мне кажется, это также будет служить той же цели, будь то класс cacheobjectcontainer, logger или Classloader.

Пожалуйста, помогите мне понять вышеприведенную концепцию, где статическая переменная экземпляра не решает цель и класснужно объявить Синглтон?

Отредактированная часть

Хорошо, позвольте мне внести некоторую ясность.Цель одноэлементного класса - сохранить только один экземпляр одноэлементного класса в jvm.Согласовано.Но я пытаюсь придумать причины, по которым мы хотим сохранить только один экземпляр. Причин может быть две:

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

2) Мы хотим использовать одно и то же состояние объекта в приложении.Я думал, что это главная цель объявления класса как синглтона.Но этого можно достичь, просто объявив переменные экземпляра как статические.

Но похоже, что 1 является основной причиной того, что любой класс следует рассматривать как статический, а не как причина 2, потому что это может быть достигнуто и с помощью статической переменной.

Это правильно?

Ответы [ 4 ]

8 голосов
/ 26 августа 2011

Объявление переменной экземпляра делает эту ссылку статическим объектом.Это означает, что существует только один экземпляр этого класса , который .Но это не мешает другим делать new SomeObject() независимо от того, является ли это статической ссылкой.Идея наличия одноэлементного класса заключается в управлении экземплярами.Например, если вы сделаете конструктор private, вы не сможете сделать new для создания нового экземпляра.Следовательно, вы контролируете создание экземпляров.

4 голосов
/ 26 августа 2011

главное отличие в том, что синглтон - это обычный экземпляр, который вы можете использовать, например, в качестве параметра. Singletons также может реализовывать интерфейсы.

Маттео

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

Несколько хороших ответов.

Эта статья «Синглтон, а не синглтон» хорошо отражает концепцию.

Вот некоторые дополнительные отличия:

  • Синглтоны могут быть с состоянием, но статические переменные не могут.
  • Синглтон-классы могут быть подклассами
1 голос
/ 26 августа 2011

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

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

public class SessionManager {
    private static final SessionManager instance;
    static {
        instance = SystemConfig.isDebug() ? new DebugSessionManager() : new SessionManager();
    }

    public static SessionManager getInstance() {
        return instance;
    }


    public int getActivePersonId() {
         // default implementation
    }
}

public class DebugSessionManager : SessionManager {
    @Override
    public int getActivePersonId() {
         // debug implementation
    }
}

// The code can be used in the same way regardless of whether we're in debug mode:
int personId = SessionManager.getInstance().getActivePersonId();

Обновление

После прочтения вопроса снова звучит так, как будто вы думаете о чем-тонапример:

public class SessionManager {
    private static String systemName;
    public String getSystemName() {return systemName;}
}

... при условии, что systemName никогда не изменится, и поэтому не имеет значения, если к нему обращаются как new SessionManager().getSystemName() против SessionManager.getInstance().getSystemName().В этом случае:

  1. С семантической точки зрения, когда другой программист видит new SessionManager(), он ожидает, что что-то new создается.Не сразу очевидно, что каждый SessionManager в системе всегда будет производить один и тот же systemName.Так что синглтон может быть предпочтительнее просто для того, чтобы сделать для потребителей более очевидным, что они будут иметь дело с одноэлементным состоянием.
  2. При создании new SessionManager() возникают очень небольшие накладные расходы, которые впоследствии должны быть мусором.Собрание.

Кроме этого, вы будете иметь те же преимущества и недостатки с этим подходом, как если бы вы использовали Singleton.Я еще раз повторю свое предыдущее утверждение: синглтоны - это анти-паттерн.Предпочитают внедрение зависимостей.

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