2015-06-19 2 views
7

Я пытаюсь создать одноэлементный класс в Java. Лучшее доступное решение с версиями Java5 и выше, похоже, использует enum. Но я не уверен, как преобразовать свой класс в одноэлементный класс, используя enum. Ниже мой упрощенный класс:Как создать одноэлементный класс с использованием enum

public class Employee { 
    private int id; 
    private String name; 
    public Employee() {} 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

Когда я искал ответы в сети я нашел следующий код:

public enum EasySingleton{ 
    INSTANCE; 
} 

Но где мои переменные и методы класса? Я не уверен, как это реализовать. Я знаю, что мы можем предоставить методы для enum, но где будут мои переменные? Любая помощь по этому поводу была бы очень оценена.

P.S .: Пожалуйста, не обсуждайте, являются ли синглтоны злыми или анти-шаблонами. Мне просто интересно, как создать синглтон, используя enum.

+2

Вы бы поместили их в перечисление. Но наличие * изменчивого * перечисления было бы очень странным - и наличие изменчивого синглтона было бы странным. «Сотрудник» просто не чувствует себя как естественный синглтон. –

+0

Посмотрите [здесь] (https://bitbucket.org/vadimvera/java-design-patterns/) и [здесь] (https://bitbucket.org/vadimvera/java-standard-edition/src/d0ae9863354c48291cc4ff0e91e9f80fd96fdce2/ src/main/java/io/shido/patterns/Singleton.java? at = master) ... хотя ваш класс выглядит как обычный класс –

+0

Пожалуйста, обратитесь к этому: [post] (http://stackoverflow.com/a/2912312/2928710) –

ответ

11

Различия между классом и перечислением не так велики. Я изменил первую строку кода на public enum вместо public class и добавил имя вашего экземпляра.

public enum Employee { // changed "class" to "enum" 

    INSTANCE; // added name of the (single) instance 

    private int id; 
    private String name; 
    Employee() {} // removed "public" 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

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

Кроме того, перечислений имеют некоторые другие специальные функции:

  • Вы не можете extend другого класса (только implements)
  • Некоторые предопределенные методы (например, static values() и getName()) доступны
  • конструкторы могут быть только пакет частный или частный
+0

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

+0

Несомненно, но что вы на самом деле подразумеваете под «запускать свой код несколько раз в одном vm»? – gabriel

+1

@ gabriel Скажем, вы пишете простую игру в тетрис. В одном игровом поле в качестве входных данных используются клавиши «W, A, S, D». Теперь вы решаете, что хотите сделать его многопользовательским - с двумя игровыми полями, один пользователь использует «W, A, S, D», другой пользователь «I, J, K, L». Если ваш код использовал множество «статических» переменных, будет сложно «позволить ему работать дважды» (один раз для каждого игрока). Повторное использование кода намного проще, если вы избегаете статических переменных. – slartidan

1
public enum SingletonEnum 
{ 
    INSTANCE; 

    public void doStuff() 
    { 
     System.out.println("Singleton using Enum"); 
    } 
} 

И это можно назвать от клиентов:

public static void main(String[] args) 
{ 
    SingletonEnum.INSTANCE.doStuff(); 
} 
3

Ваш класс «Сотрудник» это на самом деле не то, что должно быть синглтон, но здесь идет.

public enum Employee { 
    INSTANCE; 

    private int id; 
    private String name; 

    private Employee() {} //enum constructor must be private 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

Затем вы можете сделать

Employee.INSTANCE.setName("Hello World!"); 
1

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

Эффективная Java-технология Блоха имеет приятное обсуждение этого вопроса. См. Стр. 17-18. Я берусь прямо из этой ссылки!

В принципе, вы можете принудительно применять шаблон singleton с перечислением или частным конструктором. Блох предпочитает прежний, хотя он менее распространен.

например.:

// Enum singleton 
public enum Elvis { 
    INSTANCE; 
    public void leaveTheBuilding() { ... } 
} 

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

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