Si je peux me permettre, tout ceci n'a guère de sens. En fait, ce n'est pas vraiment traduisible en Java. La manière d'écrire les singletons en Java est nettement plus simple qu'en C++ (même multi-thread-safe ; et en l'occurrence, l'écriture est plus simple que ce qu'a écrit Anonymouse). Elle est tellement simple qu'elle rend inutilement complexe toute tentative de factoriser le code de création du singleton.
Si on essaie de le faire quand même, voici ce que ça donne, étape par étape, et on verra là où ça va finir par coincer.
Le truc fondamental avec les templates C++, c'est que le compilateur pioche dans le code template pour ne compiler que ce dont il a besoin. Si une classe template n'est pas utilisée, il ne la compile pas. Si une classe template utilisée a une de ses méthodes qui n'est pas utilisée, il ne compile pas cette dernière. Et surtout, on peut faire des suppositions sur les types templates (ici, il existe une méthode instance() sur le type T) sans le dire vraiment. On peut donc tout à fait écrire du code template C++ qui ne compile pas (en tout cas pas tout seul), alors même que le compilateur C++ n'affiche aucune erreur à la compilation.
En Java, le compilateur compile toujours l'intégralité des classes génériques. Il vérifie donc la syntaxe de tout leur code. Et en plus, il faut impérativement dire ce qu'on suppose sur les types génériques.
Ainsi, si on suppose que le type T possède une opération instance(), il faut écrire un truc du genre :
Code :
- interface Singleton<T> {
- T instance();
- }
- class SingletonCreator<T extends Singleton<T>> { ... }
|
Le problème ensuite pour traduire ton code de C++ en Java, c'est qu'on se retrouve face à une autre limitation des génériques Java : dans la version C++, l'opération instance() sur T est statique ; c'est donc une opération qui porte sur la classe T elle-même, et non une opération qui porte sur une instance de T.
En Java, il n'y a aucun moyen d'exprimer une telle chose : les opérations dans les classes génériques ne peuvent être définies que comme des opérations qui portent sur des instances. Et quand on a un type générique T en Java, on ne peut pas non plus écrire "new T()" ou "T.class"
Bref, c'est peut-être possible en utilisant les éléments les plus poussés de l'introspection (package java.lang.reflect), mais je ne connais pas vraiment de moyen de factoriser le code de création d'un singleton. En même temps, y a-t-il vraiment besoin de factoriser ceci (qui est thread-safe) ?
Code :
- public class MonSingleton {
- private static final MonSingleton instance = new MonSingleton();
- private MonSingleton() {
- ...
- }
- public static MonSingleton getInstance() {
- return instance;
- }
- }
|
Message édité par BifaceMcLeOD le 11-04-2008 à 11:29:30