10
votes

Création d'une classe de base Singleton dans PHP 5.3

droit au point: J'ai deux cours singletons, tous deux héritant leur nature singleton d'une super-classe. J'initialise certaines propriétés sur le premier singleton, puis avez le deuxième singleton récupérer l'instance forte> du premier. Cette instance, cependant, ne semble pas être celle que j'ai initialisée en premier lieu. Quelque exemple de code pourrait aider à expliquer ceci:

Premièrement, la super-classe, fournissant à Singleton Nature (nécessite PHP 5.3 ou plus): P>

true
false


9 commentaires

C'est la première fois que j'ai jamais rencontré le comportement singleton hérité. Que ce soit ou non syntaxiquement correct, c'est assez étrange.


Un singleona ne sera jamais un exemple de singletonb, même s'ils sont tous deux singletons; Le mot clé statique sera sûr de cela.


Pourquoi ne pas simplement utiliser un singleton?


Juste, je ne pense pas que j'ai réussi à communiquer cela assez clairement. Je ne m'attends pas à ce que Singletona et SingleTonb soit un seul et même instance. Bien au contraire, ils sont deux instances distinctes de deux types distincts. Ils partagent un ancêtre commun, ce qui en fait des types singletons, mais ce n'est pas le type de code de test récupère. Je souhaite que le code de test définit une valeur de champ dans SingleNa, puis je veux singletonb (qui est un exemple différent, complètement) pour récupérer l'instance SingleSona et pouvoir récupérer la valeur de son champ.


@Spender: Pourquoi est-ce étrange? Je travaille sur un projet nécessitant au moins 10 classes de singletons différents. Pourquoi écrire le même code 10 fois?


Êtes-vous sûr de vraiment avoir besoin de 10 singletons différents? C'est le genre de chose qui produit durement à déboguer / tester des problèmes comme celui que vous avez ici. Si vous avez passé une instance d'un paramètre à un paramètre sur le constructeur de B (et A et B n'étant pas singletons), vous n'auriez pas eu ce problème en premier lieu.


@rojoca Je vais admettre que cela se trouve sur une étape expérimentale, mais l'idée de cette architecture est d'utiliser des classes de gestionnaires, implémentées comme singletons, pour traiter des bases de données, des systèmes de fichiers, des courriers électroniques et ainsi de suite. La plupart des classes de gestionnaire s'appuieront sur l'accès à une base de données, que le gestionnaire de base de données les fournit avec. En mettant en œuvre le gestionnaire de base de données en tant que singleton, il peut être configuré une fois pendant "Démarrage" et toutes les classes nécessitant l'accès à la base de données peuvent simplement appeler la classe Manager de base de données, sans avoir à lui fournir la configuration dont il a besoin. La même chose va avec le responsable de messagerie.


@johan. J'ai commencé à écrire un commentaire, mais j'ai manqué de chambre, j'ai donc écrit ma réponse comme une réponse.


@Johan J'ai renommé la question pour faciliter la recherche de personnes ayant des problèmes similaires.


4 Réponses :


0
votes

Je suis à peu près sûr que c'est parce que vous utilisez des méthodes statiques, qui ne sont pas instanciées.


0 commentaires

0
votes

singletona et singletonb sont différentes classes. Bien qu'ils héritent de la même classe, ils sont des cours séparés et ils ont donc différentes instances statiques.

Si vous modifiez votre code pour obtenir 2 instances de singletona ou 2 instances de singletonb , vous verrez le comportement que vous attendez. Mais parce qu'ils sont différentes classes, elles ne sont pas les mêmes singleton.


0 commentaires

13
votes

Essayez d'utiliser isset plutôt que instanceof : xxx


4 commentaires

Merci Lonesomeday, mais cela me donne le même instance, ce qui n'est pas ce que je veux.


@Johan tu as raison, ça fait. Désolé pour ça. J'ai réécrit votre classe en utilisant une gamme d'instances dans Singleton :: $ Instances , qui fonctionne.


Merci un million, homme! Cette version fonctionnera même sur les versions PHP <5.3, autant que je sache. Mais je ne comprends toujours pas pourquoi ça n'a pas fonctionné.


Il ne fonctionnera pas avant 5,3, car get_called_class a été introduit avec statique en 5.3. Et je ne suis pas sûr de ce que le problème était soit!



0
votes

Parlons OO. :)

singletona et singletonb est de type singleton

Ainsi, on peut dire:

singletona est singleton

et

singletonb est singleton

I.e. Ils sont tous les deux singleton

La signification attendue de singleton signifie qu'il ne peut y en avoir qu'un. Beaucoup de personnes d'un antécédents OO utilisant votre code seront confus.

généralement, la mise en œuvre de Singleton serait par classe car la plupart des langues OO ne seront pas pliées pour permettre l'intention de ce que vous proposez.

que php peut faire (via get_called_class () magie) ne signifie pas que cela devrait.

Je peux absolument accepter cela d'un point de vue utilitaire, la réponse acceptée a l'air bien. Compte tenu de la nécessitation de la réponse acceptée, je proposerais un changement de nom qui ne conflit pas la mise en œuvre du singleton "standard". D'un point de vue strict oo, on ne pourrait jamais hériter d'un singleton, il a donc vraiment besoin d'un nom différent.


2 commentaires

Merci d'avoir pris le temps de répondre de manière aussi généreuse. Je ne demanderai pas beaucoup d'expertise en ce qui concerne la théorie derrière le schéma singleton, mais que je suis d'accord Singletona et Singletonb, vous pouvez également dire que les deux cas de Singleton, ils sont également des cas de types distincts. Je n'ai pas été en mesure de trouver une définition adressant l'aspect héritabilité du modèle, mais de la manière dont je le vois, est que si une jungle ne peut contenir qu'un seul tigre et un lion, ils peuvent tous les deux coexister même s'ils sont les deux félins. Encore une fois, je ne prétends pas une plus grande connaissance de cela que celle de mes propres ravines.


Je sais ce que tu veux dire ici, et je ne concevrais pas quelque chose avec plusieurs singletons de toute façon (j'en utiliserais un au plus, et stockerais tous les autres cas dans celui-ci). Je conviens que ce serait mieux (a) de renommer la classe de base comme basesingleton ou quelque chose de similaire.