Hériter d'un singleton - Java - Programmation
Marsh Posté le 15-11-2002 à 14:34:00
qu'est ce que tu apelles singleton ?
montre la définition de cette classe ...
Marsh Posté le 15-11-2002 à 14:49:40
Tout dépend de la façon dont est définie l'instance de ton singleton....Et la raison qui motive un héritage...Hériter d'un singleton, je vois pas l'intérêt., là comme ça....Tu as un exemple de cas d'utilisation, histoire qu'on se fasse une idée??
Marsh Posté le 15-11-2002 à 14:58:30
Singleton de base :
Code :
|
Si tu hérites de ça, la méthode getInstance n'aura pas à être surchargée (la valeur de retour devra être du type de la nouvelle class, donc la signature sera différente).
Au mieux, tu peux peut être faire un truc du style, ms c plus tout à fait un vrai singleton :
Code :
|
L'histoire du ClassCastException, c le seul pb que j'vois au premier abord...
Marsh Posté le 15-11-2002 à 15:16:58
ouais, ou alors dans l'optique de faire qqchose du genre :
Code :
|
mais bon, pour faire un truc comme ça, jc'est pas dit que l'héritage soit indispensable..
Marsh Posté le 15-11-2002 à 15:24:20
les singleton avec les méthodes static capudubec !
Factory Rulez !!!
Code :
|
Code :
|
Code :
|
Marsh Posté le 15-11-2002 à 15:25:28
et avec ca, tu fais de l'héritage comme tu veux ! t'es plus emmerdé avec les statics !
de toute façon, j'ai arrêté les statics : ca devrait pas exister en java !
Marsh Posté le 15-11-2002 à 15:30:43
benou> Dès que tu maintiens des caches dont la durée de vie est susceptible d'être supérieure à la durée de vie usuelle d'un objet (exemple, sur un serveur), tu as besoin d'objets statiques.
Le pattern du singleton permet justement de faire ça à peu près proprement.
Marsh Posté le 15-11-2002 à 15:31:30
ouais, bon, on peut faire avec des factory aussi, ça revient exactement, au même : tu aura de toutes façons un appel statique pour obtenir une instance, alors bon....
Ce que je fais habituellement, c'est que je fais une factory quand j'ai plusieurs Singletons qui travaillent sur le même bouzin....Genre :
Code :
|
Mais bon, si j'ai par exemple, un truc qui gère des properties système, et que je sais n'avoir aucun droit en écriture sur ces machins, ben je me passe de factory : ça fait une classe de moins....J'ai juste les classes PropertyReader et PropertyReaderImpl.....
Marsh Posté le 15-11-2002 à 15:32:43
El_Gringo a écrit a écrit : public static TestSingletonExtentded getInstance () throws ClassCastException { if (ourInstance == null) { ourInstance = new TestSingletonExtentded (); } return ((TestSingletonExtentded)ourInstance) } private TestSingletonExtentded () {} }[/cpp] |
J'ai peur qu'en utilisant ici le ourInstance défini dans la classe mère, "j'écrase" l'instance de cette classe mère par ma nouvelle instance de nouvelle classe, et que du coup, tout ceux qui utiliseront encore la classe mère utiliseront plutôt la nouvelle classe (je ne sais pas si c'est clair, mais c'est ça). Impression ?
Marsh Posté le 15-11-2002 à 15:36:14
En fait, il vous manque une donnée : le singleton que je souhaite hérité, je ne peux pas le modifier, ce n'est pas moi qui l'ai développé, on me le donne compilé
Marsh Posté le 15-11-2002 à 15:40:35
Pour ton message d'avant, là, "l'écrasement" de la valeur ourinstance, ouais, normalement, ça va tout te pourrir....
Mais tu dois modifier quoi, de ton singleton?? Son comportement?? Le retour de certaines méthodes???
Marsh Posté le 15-11-2002 à 15:42:16
tu peux pas faire un deuxieme singleton qui va déleguer ce qu'il faut au premier ?
Marsh Posté le 15-11-2002 à 15:48:00
_Mac_ a écrit a écrit : J'ai peur qu'en utilisant ici le ourInstance défini dans la classe mère, "j'écrase" l'instance de cette classe mère par ma nouvelle instance de nouvelle classe, et que du coup, tout ceux qui utiliseront encore la classe mère utiliseront plutôt la nouvelle classe (je ne sais pas si c'est clair, mais c'est ça). Impression ? |
Ha, bah oui, ça c sûr !
Ms ça dépend du comportement que tu veux.
Ce que j't'ai donné, ça fait que les 2 classes sont en fait un seul singleton...
Marsh Posté le 15-11-2002 à 15:56:23
BifaceMcLeOD a écrit a écrit : public static void main(String[] arguments) { ... } |
ce n'est qu'un point d'entré. C'est le seul truc static que j'ai dans mes programmes
Marsh Posté le 15-11-2002 à 15:57:07
BifaceMcLeOD a écrit a écrit : benou> Dès que tu maintiens des caches dont la durée de vie est susceptible d'être supérieure à la durée de vie usuelle d'un objet (exemple, sur un serveur), tu as besoin d'objets statiques. |
pas du tout !
La durée de vie d'un objet n'a rien à voir avec les statics !
Marsh Posté le 15-11-2002 à 16:02:01
gfive a écrit a écrit : ouais, bon, on peut faire avec des factory aussi, ça revient exactement, au même : tu aura de toutes façons un appel statique pour obtenir une instance, alors bon.... |
ben non. Quand un objet à besoin d'accéder au singleton, soit tu lui file le singleton, soit tu lui passe l'instance de la factory. Cette Factory doit être construit une fois au début du programme et diffusée aux objet qui en ont besoin.
Le static c'est nul : imaginez le cas d'une appli serveur. Vous pourrez pas déployer votre appli 2 fois sur le même serveur si elle se sert de trucs static.
Et puis sur les projets un peu gros c'est arhituctéralement parlant très mauvaise : les méthodes static peuvent être appelées depuis n'importe quel objet de la JVM ! On a aucun contrôle là dessus.
Marsh Posté le 15-11-2002 à 16:34:52
benou a écrit a écrit : ben non. Quand un objet à besoin d'accéder au singleton, soit tu lui file le singleton, soit tu lui passe l'instance de la factory. Cette Factory doit être construit une fois au début du programme et diffusée aux objet qui en ont besoin. Le static c'est nul : imaginez le cas d'une appli serveur. Vous pourrez pas déployer votre appli 2 fois sur le même serveur si elle se sert de trucs static. Et puis sur les projets un peu gros c'est arhituctéralement parlant très mauvaise : les méthodes static peuvent être appelées depuis n'importe quel objet de la JVM ! On a aucun contrôle là dessus. |
Mais... on peut pas faire un singleton dans utiliser les statics. Pourtant les singleton, c qd même difficile de s'en passer.
Et puis tes classes utilitaires que t'as passé quelques fois, elles ont que des méthodes statiques....
Marsh Posté le 15-11-2002 à 16:45:42
gfive a écrit a écrit : Pour ton message d'avant, là, "l'écrasement" de la valeur ourinstance, ouais, normalement, ça va tout te pourrir.... Mais tu dois modifier quoi, de ton singleton?? Son comportement?? Le retour de certaines méthodes??? |
En gros, oui : l'idée était de pouvoir faire un super.maMethode dans les surcharges quand ça m'arrange, et conserver certaines autres méthodes. Le truc classique, quoi !
Marsh Posté le 15-11-2002 à 16:51:48
El_Gringo a écrit a écrit : Mais... on peut pas faire un singleton dans utiliser les statics. Pourtant les singleton, c qd même difficile de s'en passer. Et puis tes classes utilitaires que t'as passé quelques fois, elles ont que des méthodes statiques.... |
ouais mais c'est de la fainéantise ... c'est plus pratique pour tester.
et puis bon, c'est vrai que j'y susi allé un peu fort : il peut être util d'utiliser des statics, mais que dans des cas très limités.
Par exemple, pour des méthodes utilitaires c'est complétement normal d'utiliser des statics.
Pour des trucs qui seront toujours générale à la JVM aussi genre des méthodes permettant de copier des fichier ou des trucs dans le genre. Mais il faut vraiment que le choix soit raisonné !!
souvent les gens mettent un static à la vavite parce que c'est plus pratique à utiliser.
Et pusi quand on parle de singleton, n'oublie pas que si tu utilise le static ce sera un singletno pour toute la JVM ! pas seulement pour ton appli !
Marsh Posté le 15-11-2002 à 17:23:04
Benou : beuh....pour un serveur, tu va pas le lancer 2 fois dans le même process, quand même....Et 2 instances de JVM qui tournent sur une même machine ne partagent pas leurs static, hein!!
Et bon, un serveur qui écoute sur un port donné, amuse toi à en lancer 2 instances sur une même machine, qu'on rigole! D Et si c'est 2 instances avec un port différent, ben ça peut pas être statique, CQFD, et toc!
D
Enfin bon, c'est vrai, le static, on dit souvent que c'est mal, et tout, mais bon, par expérience, ça sert, quand même....
Regarde, bêtement, un système de logger, ou de gestion de connection DB....Ben il vaut mieux que ce soit statique, ce genre de bouzin, que tes streams se marchent pas dessus, non??
Marsh Posté le 15-11-2002 à 17:48:23
qu'est ce que tu racontes ??? pfioulala !!
prend le cas d'un conteneur de servlet. Si tu as écris une API avec des statics partout, tu ne pourra pas utiliser cette API dans 2 web-app (2 sites) sur le même serveur ! ou bien bravo les effets de bord !
les exemples que tu sites sont typiquement ceux que j'aurais utilisé comme contre exemple
Si ton logger est static, 2 sites Web sur le même serveur vont mélanger leurs logs dns le même fichier. Pareil pour la gestion de connection à la base de donnée !
En gros faut voir ce que tu veux faire :
- si ce que tu veux c'est faire un petit traitement indépendants à ton appli (genre des petites méthodes utilitaires, etc ...), des méthodes statiques sont parfaitement adaptés
- si ce que tu veux faire c'est rendre un service (de logging, de management de connexion DB, etc) pour une application, C'est des objets qu'ils faut utiliser et les passer à tes classes qui en ont besoin.
Marsh Posté le 15-11-2002 à 17:52:15
benou a écrit a écrit : pas du tout ! La durée de vie d'un objet n'a rien à voir avec les statics ! |
Dès lors que l'on vit dans un monde (Java) où la durée de vie est liée à l'attachement (en anglais, reachability), si. Parce qu'il faut, pour que l'objet continue à vivre, qu'une référence sur lui existe. Et le plus simple pour obtenir cela, c'est qu'un symbole le référençant existe depuis la naissance de l'objet jusqu'à sa mort.
Donc si l'on veut disposer d'un objet dont la durée de vie soit celle du programme, je ne vois pas beaucoup de moyens autre que l'objet statique (à part bien sûr la persistance... ), i.e. un objet qui existe tant que sa classe existe.
Marsh Posté le 15-11-2002 à 17:53:45
houlala ...
dis moi que t'es pas sérieux s'il te plait ...
Marsh Posté le 15-11-2002 à 17:56:28
benou a écrit a écrit : ben non. Quand un objet à besoin d'accéder au singleton, soit tu lui file le singleton, soit tu lui passe l'instance de la factory. Cette Factory doit être construit une fois au début du programme et diffusée aux objet qui en ont besoin. Le static c'est nul : imaginez le cas d'une appli serveur. Vous pourrez pas déployer votre appli 2 fois sur le même serveur si elle se sert de trucs static. |
Ben non, gros malin : quand on lance 2 fois l'appli, elle tourne dans 2 JVM différentes (c'est d'ailleurs un gros b... pour les faire communiquer derrière...)
Citation : |
Encore une erreur. D'abord, les méthodes statiques sont sujettes à la protection habituelle (public/privé/protégé), et précisément sur un gros serveur, tu as souvent besoin d'un contexte global, dont l'accès sera évidemment synchronisé si tu as plusieurs threads.
L'avantage du singleton est précisément de plaquer la notion de boite noire et d'encapsulation sur la notion de variable globale, et permet de retrouver du contrôle, puisque l'accès aux différents "champs"/"éléments"/ce-que-tu-veux de la ou les variables globales se fait/font uniquement par des accesseurs, comme pour tout objet qui se respecte.
Marsh Posté le 15-11-2002 à 17:56:49
Ben....je suis pas forcément d'accord, hein..nottament pour le gestionnaire de connections : si tu as un pool de connections, il est indispensable que ce soit le même pour tout le monde....Et pour un logger tu peux vouloir du mélange, justement, si tu fais, par exemple, un système où tu dois logger en "temps réel", je veux dire par là, si l'ordre des actions est important (typiquement, outil de stat pour des jeux de rapidité, ou comme ça) ben...t'as besoin que ça se mélange..
Marsh Posté le 15-11-2002 à 18:00:51
Désolé, je viens juste de lire les derniers posts... Je vois que j'avais du retard...
benou> Tu cites le cas des logs ou des connexions à la BD. Mais justement dans ces cas-là, on va utiliser un gestionnaire centralisé, parce qu'il s'agit d'une ressource critique. Et ce gestionnaire centralisé, que va-t-il contenir ? Un table de hachage basé sur le thread courant. Effectivement, on aurau autant de loggeurs et de connexions BD que de clients connectés dans notre serveur, mais on y accédera quand même par un singleton, donc in fine un attribut statique.
edit> Encore trop tard
Marsh Posté le 15-11-2002 à 18:01:03
gfive a écrit a écrit : Ben....je suis pas forcément d'accord, hein..nottament pour le gestionnaire de connections : si tu as un pool de connections, il est indispensable que ce soit le même pour tout le monde....Et pour un logger tu peux vouloir du mélange, justement, si tu fais, par exemple, un système où tu dois logger en "temps réel", je veux dire par là, si l'ordre des actions est important (typiquement, outil de stat pour des jeux de rapidité, ou comme ça) ben...t'as besoin que ça se mélange.. |
tu peux le vouloir, mais c'est pas forcément ce que tu veux faire. C'est tout à fait naturel de vouloir que 2 sites webs différents aient des logs différents ...
Marsh Posté le 15-11-2002 à 18:02:12
Ca "marche" comment un objet qui contient une méthode statique ? Que fait la JVM quand elle voit une telle classe ?
Marsh Posté le 15-11-2002 à 18:03:03
Mais j'ai pas dit que c'était la panacée non plus, hein!! C'est pas adapté à toutes les utilisations! Mais il y a des cas où tu en as absoluement besoin!
Marsh Posté le 15-11-2002 à 18:07:22
BifaceMcLeOD a écrit a écrit : Ben non, gros malin : quand on lance 2 fois l'appli, elle tourne dans 2 JVM différentes (c'est d'ailleurs un gros b... pour les faire communiquer derrière...) |
... t'as du comprendre dans mon autre post ce que je voulais dire. Un autre exemple : les serveurs d'applications (EJB, etc ...) 1 serveur = plusieurs applications
donc si ces différentes applications utilisent la même API qui a des trucs statics où il ne faut pas, ca va pas bien marcher !
BifaceMcLeOD a écrit a écrit : Encore une erreur. D'abord, les méthodes statiques sont sujettes à la protection habituelle (public/privé/protégé), et précisément sur un gros serveur, tu as souvent besoin d'un contexte global, dont l'accès sera évidemment synchronisé si tu as plusieurs threads. |
J'ai jamais parlé des problèmes d'accès concurent ... ca n'a rien à voir
BifaceMcLeOD a écrit a écrit : L'avantage du singleton est précisément de plaquer la notion de boite noire et d'encapsulation sur la notion de variable globale, et permet de retrouver du contrôle, puisque l'accès aux différents "champs"/"éléments"/ce-que-tu-veux de la ou les variables globales se fait/font uniquement par des accesseurs, comme pour tout objet qui se respecte. |
Je ne remet pas en cause la notion de singleton. C'est juste que rendre un singleton static c'est faire un singlton pour toute la JVM ! pas seulement pour une application ...
regarde dans toutes les API connues, il n'y quasiment aucun static ou bien seulement pour des petites fonctions utilitaires.
Marsh Posté le 15-11-2002 à 18:07:42
Ben, j'imagine (mais je sais pas) que c'est le ClassLoader qui fait ça : quand il charge la classe, il réserve la mémoire et les pointeurs pour les attributs statiques, et il exécute tout ce qui est dans un champ static { }
A ce propos, Benou, après réflexion, pour les Web-apps, Tomcat utilise un ClassLoader par zone....donc, si tu te démerdes bien avec tes fichiers .class, tu dois pas être emmerdé..
Marsh Posté le 15-11-2002 à 18:10:38
gfive a écrit a écrit : Mais j'ai pas dit que c'était la panacée non plus, hein!! C'est pas adapté à toutes les utilisations! Mais il y a des cas où tu en as absoluement besoin! |
Ben y en a pas des masses : y a le cas de la méthode main et le cas d'un Singlton pour la JVM (genre le system.out, un générateur d'identifiant uniques etc ...).
Les autres utlisations c'est plutot pour une raison de facilité : les méthodes utilitaires , etc ...
Marsh Posté le 15-11-2002 à 18:13:07
gfive a écrit a écrit : Ben, j'imagine (mais je sais pas) que c'est le ClassLoader qui fait ça : quand il charge la classe, il réserve la mémoire et les pointeurs pour les attributs statiques, et il exécute tout ce qui est dans un champ static { } A ce propos, Benou, après réflexion, pour les Web-apps, Tomcat utilise un ClassLoader par zone....donc, si tu te démerdes bien avec tes fichiers .class, tu dois pas être emmerdé.. |
C'est pas le ClassLoader qui fait ca : c'est un méchanisme interne à la JVM.
Ta remarque es pas conne : est ce que 2 classes chargées par 2 ClassLoader sépareés ont leurs attributs statiques communs ?
Je voterai pour oui, mais ca demande un petit test. (je reviens tout à l'heure )
Marsh Posté le 15-11-2002 à 18:16:29
remarque : dans le cas où tu fosu le jar dans la partie common pour que toutes les webapp puissent se servir de l'API, le ClassLoader sera le même. Donc y a au moins un problème pour ce cas là !
Marsh Posté le 15-11-2002 à 18:24:25
ouais, effectivement, ça demande un bidouillage savant pour pas se planter, mais bon...On a eu des cas à la con, comme ça, au boulot, pour adapter une appli pensée en single client vers du multi-client....Ben c'est une galère!
Enfin bon, on peut en débattre 107 ans sans jamais arriver à tomber d'accord
Mais t'es quand même un furieux d'aller tester ça u vendredi à 18h27!
Marsh Posté le 15-11-2002 à 18:33:23
c'est clair
mais bon, je suis super curieux ... on me changera pas !
j'ai testé, et effectivement, 2 classes identiques chargés par des ClassLoader différents n'ont pas leurs attributs statics communs.
J'aurais vraiment pas cru ! j'ai appris un truc aujourd'hui
Marsh Posté le 15-11-2002 à 18:35:11
bah heureusement!........ou pas!! D
Bon, bière/fléchettes time, sur ce!
Marsh Posté le 15-11-2002 à 20:51:46
bah dans le cas des web-app, le mieux c'est encore d'instancier les singletons dans un listener et de les ratacher au contexte applicatif, non ?
Marsh Posté le 15-11-2002 à 14:29:23
Toujours dans mes grands délires sur les singletons, je me demandais s'il était contre-indiqué d'hériter d'un singleton ? N'y a-t-il pas un risque "d'effet de bord incontrolable" (notamment, problème d'instanciation) ? La classe héritante est-elle aussi un singleton ? Si non, comment faire pour qu'elle en soit un aussi ?