2016-02-25 5 views
0

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

public class Singleton { 
    private static Singleton instance; // attributes omitted 
    private Singleton() { 
    // omissions 
    } 

public static Singleton instance() { 
    if (instance == null) { 
     instance = new Singleton(); 
    } 
    return instance; 
} 
// other methods omitted 
} 

public class Singleton { 
    private static int bound = 1; 
    public Singleton() { 
    if (bound == 0) { 
     throw new RuntimeException(
     "Singleton: No more objects must be created"); 
    } 
    bound--; 
} 
} 

который является предпочтительным использовать и почему? Они одинаково хороши?

+3

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

ответ

3

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

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

2

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

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


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

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

  • Если вы можете инициализировать экземпляр жадности, просто сделать это:

    class Singleton /* extends Blah */ { 
        private static final Singleton INSTANCE = new Singleton(); 
    
        static Singleton getInstance() { return INSTANCE; } 
    } 
    
  • Если вы хотите отложить инициализацию, пока она не требуется, вы можете использовать ленивый держатель идиомы:

    class Singleton /* extends Blah */ { 
        private static class Holder { 
        private static final Singleton INSTANCE = new Singleton(); 
        } 
    
        static Singleton getInstance() { 
        return Holder.INSTANCE; 
        } 
    } 
    

    Класс Holder не инициализирован до getInstance(), поэтому экземпляр Singleton не создается до этого момента.

Следует отметить, что singletons are considered by some to be a design antipattern.

Смежные вопросы