Singleton comment ça marche ?
geekspirit
Membre
Bonsoir,
Je m'intéresse de prêt au singleton. Il semblerait que sa me permette d'utiliser les mêmes fonctions dans tout le code de mon projet. J'ai fais quelques recherche qui m'ont permisent d'avoir le code source type d'un sigleton. Mais je trouve beaucoup moins d'information au niveau général ou d'exemple d'utilisation.
D'où des questions comme : comment l'utiliser ? Comment le gérer au niveau de la mémoire ? Il faut le déclarer dans chaque classe ? Il faut faire un alloc init la première fois ? Comment l'utiliser dans plusieurs classe ? ...
Si quelqu'un peu m'expliquer un peu le principe et surtout comment l'utiliser ?
Merci
Je m'intéresse de prêt au singleton. Il semblerait que sa me permette d'utiliser les mêmes fonctions dans tout le code de mon projet. J'ai fais quelques recherche qui m'ont permisent d'avoir le code source type d'un sigleton. Mais je trouve beaucoup moins d'information au niveau général ou d'exemple d'utilisation.
D'où des questions comme : comment l'utiliser ? Comment le gérer au niveau de la mémoire ? Il faut le déclarer dans chaque classe ? Il faut faire un alloc init la première fois ? Comment l'utiliser dans plusieurs classe ? ...
Si quelqu'un peu m'expliquer un peu le principe et surtout comment l'utiliser ?
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
UIApplication et NSUserDefaults par exemple sont des singletons. Pour récupérer l'instance unique de chacun de ces singletons, les méthodes sont donc sharedApplication et standardDefaults, respectivement.
Explications du concept sur la DevPedia Apple
Quelques explications.
Le principe est simple: une méthode de classe te renvoie un objet, que tu utilises comme tout autre objet. La seule différence, c'est que cet objet est unique pour toute l'application.
Le risque c'est la facilité à mon avis, quand tu ne sais pas trop comment caser une classe parce que plusieurs autres en ont besoin, c'est vite fait de ce dire: "Boaf autant en faire un singleton comme ça ya plus à avoir de référence vers cette classe".
Pour moi donc un Singleton c'est vraiment à utiliser seulement si TOUTE autre classe POURRAIT avoir besoin des services du Singleton.
Typiquement UIApplication en effet ont peut avoir besoin de ces services un peu n'importe où.
@Greensource: Tout à fait. Les Singletons posent entre-autres des problèmes pour les tests unitaires.
en Poo il existe plusieurs approches.
mais dans le fait à l'exécution on a besoin des même chose.
des objets à manipuler.
certain langages permettent de définir directement des objet d'autre non. ces dernier permettent de définir des classes d'objet qui elles-même permette de fabriquer des objets.
dans la nature, dans les modélisation qu'on fait pour écrire une application il existe des objet en un seul exemplaire. non parce qu'on en a créé qu'un seul mais parce que par nature il est unique.
si je fais un appli qui modélise notre système solaires j'ai des planètes, des satellites, des astéroà¯des, et un soleil dans le système solaire il n'y a qu'un seul et unique soleil
dans un langage permettant la définition d'objet directement je vais créer un objet soleil. mais dans un langage à base de classe je ne peux pas. je peux juste créer une classe.
je crée donc un classe étoile et je fait une instance de cette classe que j'appelle soleil. mais rien n'empêche en cours d'exécution de créer une autre étoile. et là je ne suis plus conforme à ce que je veux modéliser à savoir notre système solaire qui ne comprends qu'une seule et unique étoile.
pour palier à ce problème il me faut trouver un moyen d'empêcher la création de plusieurs étoiles.
pour cela on va passer par une fabrique.
une fabrique est une méthode qui créé et retourne un objet.
généralement on crée un méthode statique sur la classe
ainsi je peux demander à ma classe étoile de me donner le soleil et s'il n'existe pas encore de le créer.
reste que je peux continuer à instancier ma classe. pour éviter ça je vais protéger le constructeur. ainsi on ne pourra plus créer d'étoile la seul chose qu'on pour faire c'est demander à la classe le Soleil
j'ai donc un objet soleil qui n'existe qu'en un exemplaire et il ne peut en être autrement.
cet artifice introduit dans les langage à base de classe ne connaissant pas nativement la notion d'objet (il faut instancier une classe) s'appelle un Singleton.
le soleil est bien un objet ce n'est pas une classe. par exemple dans la modélisation du système solaire je pourrais avoir une classe objet céleste avec des méthodes d'instances. mes classes planète étoile satellite dérivant de cette dernière pourraient en bénéficier.
je pourrait appliquer la méthode setAlbedo de la classe objet céleste aussi bien à une planète qu'au soleil
alors que si j'avais défini une classe purement statique (en C++) soleil même si elle héritait d'objet céleste je ne pourrait lui appliquer les méthode d'instances.
une note : j'ai parlé de langage permettant la création d'objet sur le principe cela revient à
alors que pour un langage n'ayant pas cette notion
A+JYT
Ah ouais? Et Tatooine alors? :P
Bon pour pas polluer pour rien je rajoute la Doc d'Apple sur Singleton, je sais que ça fera plaisir à Geekspirit
Plus sérieusement, si parfois j'ai du mal à lire la doc (surtout un Vendredi) cette partie sur Singleton est vraiment très bien.
Sinon sekaijin je ne suis pas d'accord avec tes explications. Ou plutôt, je dirais que ton exemple est mal choisi.
Si je veux créer un programme qui me permette de modéliser une galaxie ou un système solaire, je vais justement pas faire de la classe Sun un singleton. Pourquoi en faire un singleton, alors que par nature rien n'interdit d'avoir plusieurs soleils ?
Un soleil n'est pas unique, dans d'autres systèmes (comme Tatooine :P) il peut y avoir plusieurs soleils.
Toi dans ton cas précis, tu veux représenter notre système solaire, donc en effet il n'a qu'un seul soleil. Mais justement le principe même de la POO et de langages à base de classes c'est la réutilisabilité !! Donc si tu codes des classes "Sun" et "Planet", il ne faut surtout pas penser que pour ta petite personne : si un jour tu fais un autre projet qui nécessite de modéliser d'autres systèmes ou une galaxie entière, tu vas avoir envie de réutiliser tes classes "Sun" et "Planet" que tu as déjà passé tant de temps à développer... sauf que dans cet autre contexte, tu pourras très bien avoir plusieurs soleils !
Tu dis : Eh bien pour moi c'est justement le cas de notre soleil. Il se trouve que notre terre n'a qu'un seul Soleil, mais d'autres planètes de la galaxie en ont plusieurs, donc un soleil n'est pas unique par nature. De même si jamais tu veux par exemple modéliser dans ton programme notre système solaire et son Soleil à plusieurs instants de sa vie, tu vas avoir besoin de plusieurs instances de la classe Sun, chacune ayant des paramètres différents (taille, température, etc) en fonction de l'époque que tu modélises...
Par contre, sur une application iPhone, les exemples plus justifiés de singleton sont par exemple le singleton représentant l'iPhone lui-même (UIDevice), son écran (UIScreen), l'accéléromètre de l'iPhone (UIAccelerometer), ...
Je vais faire mon chieur d'astronome mais si si le Soleil est unique!
Soleil, c'est le nom propre de notre étoile tout comme "voie lactée" est le nom de notre galaxie. :P
Après c'est vrai que si on met une majuscule, et qu'on parle donc du Soleil, on parle du coup de notre soleil, celui autour duquel tourne la Terre, alors que si on n'en met pas, c'est un nom commun (c'est pour cela que je n'ai pas mis de majuscule pour ma part)
Reste que si j'avais à créer des classes pour modéliser un système astronomique, je ferais :
- Une classe AstronomicalObject
- Une sous-classe "Star" dérivant de AstronomicalObject
- Une sous-classe "Planet" dérivant de AstronomicalObject
Et je créerais une instance "Star* sun" pour modéliser notre Soleil, et 8 instances "Planet* mercury", "Planet* venus", "Planet* earth", etc... pour modéliser notre système solaire.
Mais je ne ferais pas de "Star" un singleton, ni ne créerai de sous-classe "Sun" héritant de "Star" mais étant un singleton, je pense, car à mon sens ça n'est pas justifié.
A la limite, je rajouterais à cet arsenal une classe "SolarSystem", qui elle serait un singleton représentant notre système solaire, et étant une composition contenant les éléments précités.
Mais comme relevé par GreenSource, le pattern Singleton est bien pratique parfois, mais il ne faut pas en abuser, en particulier quand il n'est pas plus justifié que cela... ça existe, c'est bien, mais faut l'utiliser avec parcimonie, je veux dire ce n'est souvent pas nécessaire de créer un singleton (et donc d'avoir une contrainte d'unicité d'instance sur une classe) si cette contrainte ne nous sert pas et ne nous apporte pas une utilité supplémentaire. Accéder facilement depuis tout le programme au singleton UIApplication ou UIDevice, ça a un sens et est justifié. Pour la classe "Sun" (ou plutôt disons "Star"), à mon sens ça n'apporte rien d'autre qu'une contrainte (pour celui qui voudrait réutiliser ces classes dans d'autres contextes)
Oups, désoler pas pigé le DevPedia ::)
ça prouve que c'est une bonne référence
Par exemple un cas qui peut arriver souvent, c'est un objet qui doit être modifié par de nombreuses autres classes! La solution de facilité est donc effectivement de mettre cet objet en singleton comme ça tout le monde l'a directement plutot que de passer le référence a chacun d'eux! Une autre solution est de créer un singleton qui va garder la référence de cet objet! Ces deux solutions marchent parfaitement, mais d'un point de vue architecture ne sont pas satisfaisantes! Pour cet exemple précis on peut, par exemple, se servir du design pattern Observer via les NSNotification! il suffit donc que cet objet tant convoité soit abonné à un type de notifications (par exemple pour se rafraichir), ainsi pas besoin de références vers lui pour le mettre à jour, il suffit d'envoyer une notification et par magie tout marche direct!
Faut bien garder à l'esprit que le singleton est vraiment une solution de facilité, mais qu'il y a plein d'autres "modèles" beaucoup plus adaptés dans la plupart des cas!
Je ne suis pas d'accord ce n'est pas une solution de "facilité. C'est un solution ni plus ni moins. Essayes par exemple de faire coucher un système de notifications en multithread et là ça devient une usine à gaz en moins de deux en plus d'être très peu performant par rapport à un singleton. A contrario, il n'y a rien de plus simple que de rendre la classe d'un singleton thread safe.
Effectivement, je viens de m'en apercevoir après relecture. Généralement j'utilise plutôt des points d'exclamation ...
Attention, quand j'ai dit que le singleton était une solution de facilité, je ne voulais pas dire que c'était toujours une mauvaise solution... Dans certains cas c'est effectivement la solution la plus adaptée... Je voulais juste dire quand dans beaucoup de cas un singleton est utilisé alors qu'on pourrait faire mieux... (encore des points d'exclamations... ^^)
d'intérogation ?
de suspension...
Merci maxi mousse, je voulais bien dire des points de suspension
Excellent, j'ai halluneciné ! D'ailleurs si l'on pouvaient aMarssir un peu avant l'été... (ref: astronome pure malt 4 ou 5ème verres)
ce qu'il faut surtout retenir du singleton c'est qu'il est fait pour avoir un objet UNIQUE
le fait que le singleton puisse être récupéré n'importe où dans le code n'est pas dans sa nature de singleton mais du fait de l'artifice mis en oe“uvre dans la langages à base de classes.
ce servir du singleton pour avoir des fonctions qui on une portée globale est un non sens.
c'est une Verrue de la POO à base de classes.
il ne faut surtout pas utiliser le singleton pour ça. ce n'est pas fait pour ça.
A+JYT
Pour moi la POO a toujours été à base de classes (à moins que l'on inclus dedans les langages orientés prototype, comme EcmaScript, mais bon même si les concepts abordés sont propres, ce n'est plus de la POO mais de la POP :P) donc je suis intéressé par la raison de ta volonté de préciser ce "à base de classes" ?
Jm'attendais pas à engager un vrai débat !
Bon je précise un peu :
Pour moi le but c'est avoir un truc genre outils où je mettrai dedans des fonctions toutes bête comme isEmptyString qui teste si une chaine est différent de @"", @"0", nil.
Pour moi c'est le moyen d'économiser du code que je répète régulièrement de manière à aussi y voir un peut plus clair, sa simplifie mon code.
Alors c'est la bonne solution ?
Merci
Une "Category" sur la classe NSString est à mon avis bien plus adaptée à ce genre de chose qu'un singleton...
Et en tout cas pour le coup non un singleton n'est pas adapté pour ce genre de cas, car ça impliquerait de créer une instance d'un objet genre [MyTools sharedTools] qui ne représente rien de particulier, juste pour pouvoir appeler une méthode "isEmptyString:" dessus... côté architecture logicielle y'aurait aucune logique (voire ce serait un non sens). A la limite à défaut d'utiliser les catégories (même si je redis que c'est pile ce qu'il faut), des fonctions C globales pourraient être acceptables, mais un singleton n'est pas fait pour ça.
c'est le cas de tous les langages à objet à base de prototype.
en gros un prototype c'est l'équivalent du constructeur dans une classe
il n'y a pas de classe que des objets
c'est le cas par exemple de javascript qui doit être le plus rependu.
mais il existe des langages connaissant la notion d'objet et la notion de classe
Objective-c ne connait que la notion de classe et la notion d'instance
Xlisp par exemple est de ceux-la
on peut définir un objet sans classe et définir des classes pour les instancier
il existe aussi des langage à base d'agents comme jack ou jade
d'autre à base d'acteurs comme mering
en ce qui concerne les langages de programmation une toute petite partie se dispute le devant de la scène mais il en existe beaucoup
urbis par exemple est un langage permettant de développer des système fortement contraint dans le temps de traitre du paraleliste de tache des chose comme ça.
par exemple en c
pour les exécuté en parallèle c'est pas simple
exécute en urbi les deux fonction en parallèle
Réactive C et ses confères propose une programmation synchrone basé sur des évènements.
en gros tu fait plein de méthode qui s'abonne à des évènement comme dans cocoa
Reactive C inclus dans le langage le synchronisme ainsi quant un évènement survient les méthode abonnées réagissent et génèrent d'autres évènements. lorsque toutes les méthodes abonnées on fini on passe à l'évènement suivant.
très pratique pour faire un orchestrateur
Parallax lui travaille sur le parallélisme massif
ainsi une opération matricielle (produit cartésien par exemple) s'écrit en une instruction et monopolise autant d'unité de calcul que de cellules dans la matrice sans contrainte de dimension. s'il n'y a pas assez de cpu il vas simuler leur présence.
etc...
dans toutes cette foison de très nombreux langage ont la notion de POO mais pas toujours la même.
A+JYT
C'est un mauvais exemple le isEmptyString, je cherche disons à stocker des fonctions diverse, de toute nature, un genre de boite à outils général que je puisse utiliser partout et sans avoir à faire 1000 instanciations dans mon projet sinon c'est l'effet inverse. Je ne souhaite pas non plus les recopier dans chaque class.En faite je cherche à faire ce que je fait en php avec un include d'un fichier contenant des fonctions outils. Un peut comme les modules en vb
Sa sa me parait bien, surtout le mots clé global -)
Un petit exemple ou doc ? Sa marche comment ? Les Avantages ?
Merci à vous
http://fr.wikipedia.org/wiki/Programmation_orientée_objet
Il existe actuellement deux catégories de langages à objets : les langages à classes et ceux à prototypes, que ceux-ci soient sous forme fonctionnelle (CLOS), impérative (C++, Java...) ou les deux (Python, OCaml, ...).
perso, le Singleton me permet de faire communiquer des vues sans avoir de lien fort entre elles, une vue peut alors informer toutes les vues simplement
Effectivement de simples fonctions C ou les catégories c'est bien. Sinon, il y a aussi les méthodes de classe qui peuvent être utilisées.
Tu peux créer une classe genre "MyToolBox" et tu n'y mets que des méthodes déclarées avec un "+" genre:
et pour appeler ta méthode pas besoin d'instance puisque c'est une méthode de classe. Il suffit de faire:
C'est pas les solutions qui manquent!
Merci
Oui tu peux utiliser des fonctions C n'importe où vu que l'Objective-C est basé sur ce langage, et tu peux mélanger du C et de l'Objective-C. D'ailleurs le C est par exemple très utile pour faire de la récursivité.
Heu pour moi en POO, un objet, c'est une instance d'une classe. Donc par exemple en Objective-C, comme en C++ d'ailleurs ou C# ou Java, il y a des classes, et des objets qui sont des instances de ces classes. Donc j'ai du mal à saisir du coup tes explications ?
Enfin bon pour moi la définition de la POO telle que décrite par Alan Kay définit que les langages respectant la POO sont de deux types, ceux basés sur la notion de classes, et ceux basés sur la notions de prototypes... mais quand on parle de ceux basés sur les prototypes comme ECMAScript on parle de Programmation Orientée Prototype justement pour faire la différence, plutôt que de POO... non ?
[EDIT]Ah ben tiens Wikipedia, que switcherdav a cité, semble confirmer cela...