Jakie jest najlepsze podejście do używania Enum jako singletona w Javie?

85

Opierając się na tym, co napisano w pytaniu SO Najlepsza implementacja singletona w Javie - a mianowicie o używaniu wyliczenia do tworzenia singletona - jakie są różnice / zalety / wady między (pominięto konstruktor)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

a potem dzwonię Elvis.INSTANCE.getAge()

i

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

a potem dzwonię Elvis.getAge()

Miles D.
źródło

Odpowiedzi:

96

Załóżmy, że wiążesz się z czymś, co będzie wykorzystywać właściwości dowolnego podanego obiektu - możesz bardzo łatwo przekazać Elvis.INSTANCE, ale nie możesz przekazać Elvis.class i oczekiwać, że znajdzie on właściwość (chyba że jest to celowo zakodowane w celu znalezienia statyczne właściwości klas).

Zasadniczo używasz wzorca singleton tylko wtedy, gdy potrzebujesz instancji. Jeśli metody statyczne działają dobrze, po prostu użyj ich i nie zawracaj sobie głowy wyliczeniem.

Jon Skeet
źródło
1
Dlaczego nie zawracać sobie głowy wyliczeniem? Czy jest lepszy sposób na tworzenie singeltonów w java5 +?
jontro
4
@jontro (re) przeczytaj odpowiedź; mówi używać stałe teksty kiedy trzeba mieć pojedyncza ale aby uniknąć Singleton czy można zrobić z metod statycznych
nieszczęśliwy zmiennej
@MiserableVariable Skomentowałem to ponad rok temu. Naprawdę nie pamiętam, o jakim kontekście mówiłem.
jontro
nie odpowiada na zadane pytanie
Thufir
2
@Thufir: Odpowiada na część „jaka jest różnica” - która wydaje się być tym, czym OP był najbardziej zainteresowany, biorąc pod uwagę, że odpowiedź została zaakceptowana.
Jon Skeet,
69

Ogromną zaletą jest sytuacja, gdy Twój singleton musi implementować interfejs. Idąc za twoim przykładem:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

Z:

public interface HasAge {
    public int getAge();
}

Nie da się tego zrobić ze statyką ...

Nicolas
źródło
1
Można to zrobić za pomocą statystyk ... public static final HasAge INSTANCE = new HasAge () {int wiek prywatny; @Override public int getAge () {return age; }}; ... więc wciąż się zastanawiam, co jest dobre lub lepsze w metodzie enum. Przypuszczam, że gdybyś musiał zaimplementować dwa interfejsy?
Sean Adkinson,
9

(Stanowe) Singletony są zwykle używane do udawania, że ​​nie używają zmiennych statycznych. Jeśli w rzeczywistości nie używasz publicznie statycznej zmiennej, oszukasz mniej ludzi.

Tom Hawtin - haczyk
źródło
8

Wybrałbym opcję, która jest najprostsza i najbardziej przejrzysta. Jest to nieco subiektywne, ale jeśli nie wiesz, co jest najjaśniejsze, wybierz najkrótszą opcję.

Peter Lawrey
źródło