8
votes

Comment instancier un singleton plusieurs fois?

J'ai besoin d'un singleton dans mon code. Je l'ai mis en œuvre en Java et ça marche bien. La raison pour laquelle je l'ai fait est de m'assurer que dans un environnement mutillement, il n'y a qu'une seule instance de cette classe.

Mais maintenant, je veux tester mon objet singleton localement avec un test unitaire. Pour cette raison, j'ai besoin de simuler une autre instance de ce singleton (l'objet qui serait d'un autre appareil). Il y a donc une possibilité d'instancier un singleton une seconde fois à des tests ou que je dois me moquer de cela?

Je ne suis pas sûr, mais je pense que cela pourrait être possible en utilisant un chargeur de classe différent?


6 commentaires

UM .. Le nom indique qu'il ne doit y avoir qu'une seule instance. S'il ne peut pas être testé comme tel, je suggère qu'il pourrait y avoir une faille dans la conception de la classe.


N'instaduirait pas deux fois un singleton pour être un échec de test? Ceci est un comportement mauvais défini pour un singleton ...


C'est l'une des nombreuses raisons des singletons devraient être évitées comme la peste.


Sry a fait un retour par accident


Pourquoi votre test aurait-il besoin d'instancier un deuxième singleton?


simuler le même objet qui serait envoyé d'un autre appareil.


9 Réponses :


17
votes

Le point d'un singleton est que vous ne pouvez l'instancez qu'une fois.


2 commentaires

Oui c'est pourquoi je l'ai utilisé. Mais je pensais que l'on peut le faire.


@Sebi - Testez ensuite avec elle. Ou utilisez une simulacre pour tester sans cela, mais n'essayez pas de le faire quelque chose que ce n'est pas le cas.



2
votes

Vous pouvez simplement faire une autre méthode statique getInstance2 qui ressemble à ceci: xxx


2 commentaires

hmm oui, mais je devrais ensuite changer le code. Si possible, je veux éviter cela.


Je suppose que c'est un bon moyen de détruire votre code. Sur le côté plus, vos tests d'unités ultérieurs incendient des exceptions beaucoup plus souvent :-)



18
votes

Traditionnellement, un singleton crée sa propre instance et cela ne la crée qu'une seule fois. Dans ce cas, il n'est pas possible de créer une seconde instance.

Si vous utilisez une injection de dépendance, vous pouvez laisser le cadre créer le singleton pour vous. Le singleton ne protège pas contre d'autres cas (c'est-à-dire qu'il a un constructeur public), mais le cadre d'injection de dépendance instancite d'une seule instance. Dans ce cas, vous pouvez créer plus d'instances pour les tests et votre objet n'est pas encombré de code Singleton.


0 commentaires

6
votes

Un singleton, par définition, ne peut être instancié qu'une fois. Cependant, le fait que votre test de l'unité nécessite deux singletons est une indication forte que votre objet ne devrait pas vraiment être un singleton et que vous devriez repenser la conception singleton. < / p>


2 commentaires

Ou, inversement, que le test lui-même est circonspect.


Dans ce cas, il serait peut-être utile de créer une méthode resetInstance qui élimine l'instance privée à l'intérieur de la classe - cela aidera à tester de tels cas



9
votes

Vous pouvez invoquer le constructeur privé de votre classe Singleton à l'aide de la réflexion pour créer une nouvelle instance de la classe.

class MySingleton {
    private MySingleton() {
    }
}

class Test {
    public void test() throws Exception {
        Constructor<MySingleton> constructor = MySingleton.class.getConstructor();
        constructor.setAccessible(true);
        MySingleton otherSingleton = constructor.newInstance();
    }
}


4 commentaires

Bien sûr, ou vous pouvez simplement sous-classer MySingleton pour exposer le constructeur. Si vous avez du code existant qui invoque mysingleton.getinstance (). Blach (), tout ce code échouera.


C'est dans le but de tester une classe Singleton. Je ne recommande pas de faire cela dans le code sans test. Je pense qu'il est correct d'utiliser la réflexion pour atteindre des méthodes autrement inaccessibles aux fins des tests.


Je pense que c'est bien mieux de réparer le code plutôt que de pirater l'enthousiasme avec une réflexion.


Pourquoi suis-je "java.lang.noschmethodexception" avec Java6? Cela a-t-il été corrigé?



3
votes

Je me sens obligé de publier cette série d'articles sur la manière dont les singletons détruisent la testabilité et sont des choix de conception médiocres:


0 commentaires

3
votes

Premièrement, pourquoi avez-vous besoin de créer un nouveau singleton pour exécuter un test unitaire? Un test unitaire ne doit pas fonctionner simultanément avec l'application normale, vous devriez donc être capable d'accéder au singleton d'origine sans crainte de la modifier.

Y a-t-il une raison particulière dont vous avez besoin d'un deuxième singleton explicite?


0 commentaires

0
votes

singleton ston = singleton.getinstance (); retournera objet singleton. En utilisant l'objet "Ston", si nous appelons la méthode CreateNewsingletonInstance () qui est écrit à Singleton Class donnera une nouvelle instance. xxx


0 commentaires

0
votes

Vous pouvez conserver une clé sur une carte et peupler une instance avec clé xxx


0 commentaires