2012-07-12 10 views
10

W pytaniu What is an efficient way to implement a singleton pattern in Java? odpowiedź z najbardziej upvotes mówi, aby użyć Enum do implementacji singleton.Radzenie sobie z Singletonami, które mają do podklasy

To dobrze, rozumiem argumenty i zalety językowe.

Mam jednak zestaw klas, które definiuję singleton, ale które muszą rozszerzyć inne klasy, nie jest to możliwe z podejściem enum, , ponieważ wyliczenia nie mogą podklasy.

Joshua Bloch mówi w swoich slajdów:

  • Ale jedno brakuje-nie można przedłużyć typ enum
    • W większości przypadków nie powinno
    • One przekonujące kody przypadków użycia

W większości przypadków nie powinieneś: Czy ktoś może opracować na ten temat? Zaimplementowałem kilka serwletów i rozciągają się one na HttpServlet, dlaczego nie powinny być one singletonami? Chcę tylko jeden egzemplarz ich w mojej aplikacji.

+0

Proszę wyjaśnić, dlaczego chcesz serwletu singleton (jakie są ograniczenia, które doprowadziły do ​​tego wyboru)? – Romski

+0

@Romski Aplikacja wymaga tylko jednej instancji tego serwletu. – Mahoni

+0

enum może implementować interfejsy. Z delegacją oznacza to, że masz tylko jedną instancję, która używa funkcjonalności zdefiniowanej w innej klasie. –

Odpowiedz

7

Klasa Singleton może rozszerzać inne klasy; domyślnie w Javie i tak rozszerzyłoby Object. Jednak Josh ma na myśli to, że nie należy rozszerzać klasy Singleton, ponieważ po jej rozszerzeniu występuje więcej niż 1 instancja.

Odpowiadając na komentarz:

rzeczywiście najlepszym sposobem wdrożenia singleton jest:

Od Efektywna Java

// Singleton with static factory 
public class Elvis { 
private static final Elvis INSTANCE = new Elvis(); 
private Elvis() { ... } 
public static Elvis getInstance() { return INSTANCE; } 
public void leaveTheBuilding() { ... } 
} 

Tutaj Elvis może przedłużyć żadnej innej klasy.

+0

A jak to mi pomaga we wdrażaniu mojego serwletu z idiomem enum? Klasa Singleton zaimplementowana przy użyciu typu wyliczeniowego, ** nie może ** rozszerzać innych klas. – Mahoni

+0

Nie, część internetowa "Efektywna Java" mówi do podejścia enum. >> Podejście to jest funkcjonalnie równoważne podejściu w polu publicznym, z tym, że jest bardziej zwięzłe, zapewnia maszynę do serializacji za darmo i zapewnia żelazną gwarancję przeciwko wielu instancjom, nawet w obliczu wyrafinowanych ataków serializacji lub odbicia. Chociaż takie podejście nie zostało jeszcze powszechnie przyjęte, ** jednoelementowy typ enum jest najlepszym sposobem na wdrożenie singletonu ** << – Mahoni

+2

Może powinienem był powiedzieć, jeden z lepszych sposobów. Ale dla ciebie byłby to najlepszy sposób, ponieważ chcesz przedłużyć. – user1168577

1

Josh odnosi się do rozszerzenia typu wyliczeniowego, a nie do tego, aby typ singletonowy obejmował coś innego.

+0

Ale nie mogę wdrożyć mojego serwletu z idiomem singleton enum, ponieważ w ten sposób nie można podklasować 'HttpServlet':' publiczne wyliczenie MyServlet rozszerza HttpServlet' jest niedozwolone. Nie chcę przedłużać mojego singletonu, chcę pozwolić, aby mój singleton rozszerzył kolejną klasę. – Mahoni

+0

Tak, wyraźnie. Mówię tylko, że Josh nie zajmował się tą kwestią w tym cytacie;) Jest oczywiste, że nie można używać w tym przypadku idiomu enum, więc o co chodzi? –

3

Nie należy przejmować się rzeczywistą instancją serwletów - zarządzanie cyklem życia jest obsługiwane przez kontener serwletu zgodnie z umową specyfikacji serwletu, na którą się zgodziliście. Jeśli ma sens implementowanie części funkcji po stronie serwera jako singletonu, to rób to w dowolny sposób i używaj z serwletu.

+0

To ma sens! – Mahoni

+0

To pytanie rozwiązało mój problem, ale ponieważ moje pytanie było bardziej ogólne, postanowiłem sprawdzić drugie jako wyjątek. Dzięki i tak! – Mahoni

Powiązane problemy