juin
2008
Java Quiz #14
(Presque) tout le monde connait le pattern suivant :
public class MaClasse implements java.io.Serializable { private static final MaClasse INSTANCE = new MaClasse(); private MaClasse() { // ... } public static MaClasse getInstance() { return INSTANCE; } private Object readResolve() { return INSTANCE; } public void bosseUnPeu() { // ... } }
Avec les dernières versions de Java, y a-t-il une autre manière, beaucoup plus simple et concise, d'implémenter ce pattern de conception ?
Bien sûr, vous avez tous reconnu le pattern "singleton", modifié ici pour supporter la sérialisation et éviter tout conflit d'instances multiples lors d'une désérialisation.
Et qu'est-ce qui, en Java, permet de définir l'ensemble des instances d'une classe au moment de la compilation de celle-ci ? Comme l'a indiqué Bh@Mp0 dans son commentaire : les énumérations, bien sûr !
Peut-on réécrire le pattern "singleton", réécrit à la sauce enum à un seul élément ? Oui, car en Java, une enum est une classe, même si elle a des propriétés et une syntaxe particulières. En particulier, on peut y définir des méthodes spécifiques, comme ceci :
public enum MaClasse { INSTANCE; public void bosseUnPeu() { // ... } }
Non seulement cette syntaxe est fonctionnellement équivalente à la syntaxe classique (avec un attribut de classe et un constructeur privés, et une opération getInstance()
publique), tout en étant plus simple à lire et plus concise, mais en plus, elle inclut gratuitement la gestion de la sérialisation, et elle fournit une protection forte contre les instanciations multiples, y compris via l'introspection ou la sérialisation.
Bref, voilà une manière d'implémenter les singletons en Java qui mériterait de devenir la référence en la matière.
Commentaires
Le code proposé dans le commentaire précédent n'est en rien plus concis que celui de l'énoncé, et pose en plus des problèmes de performance (voir cet article).
Par contre il existe réellement un moyen simple de coder un singleton en Java 5+. Le trouverez-vous ?
enum Singleton { INSTANCE; }