Je crée une base de données pour stocker des informations sur les utilisateurs de mon site Web (j'utilise stuts2 et donc Java EE). Pour la base de données, je ferai un DBManager. Dois-je appliquer singleton modèle ici ou plutôt rendre toutes ses méthodes statiques?
J'utiliserai ce DBManager pour des choses de base comme l'ajout, la suppression et la mise à jour de profils utilisateur. Parallèlement à cela, je vais l'utiliser à toutes autres fins de recherche, par exemple pour savoir si un nom d'utilisateur existe déjà et pour obtenir tous les utilisateurs à des fins administratives et des trucs comme ça.
Mes questions
P.S. La base de données est plus grande que cela. Ici, je ne parle que des tables que j'utiliserai pour stocker les informations utilisateur.
Pourquoi le singleton et la méthode statique sont-ils vos seules options?
De mon point de vue, les deux options sont plutôt mauvaises. Lisez les Singleton AntiPattern . La plupart des cas d'utilisation du modèle Singleton sont incorrects.
Dans votre cas, j'utiliserais un objet d'instance et utiliser l'injection de dépendance (si vous utilisez un framework DI) ou un localisateur de service/modèle de registre
Avec une classe singleton, vous avez plus de contrôle sur la façon dont vous gérez l'objet créé.
Tout d'abord, un singleton est un objet. La méthode statique renvoie une instance de l'objet et vous permet de créer une seule instance, ou plus si vous le souhaitez.
Les singletons sont également chargés paresseusement, ce qui signifie qu'ils ne sont pas instanciés jusqu'à la première fois qu'ils sont appelés.
Un singleton n'utilise pas de méthodes statiques, vous n'aurez donc aucun problème à l'utiliser dans un contexte non statique.
Les singletons peuvent être étendus/sous-classés.
Puisqu'ils sont des objets, ils peuvent être injectés dans d'autres objets, ce qui permet la création de grands modèles de conception en utilisant les concepts de l'injection de dépendance. Par exemple, voici comment fonctionne le modèle Spring Bean IoC (Inversion of Control Dependency Injection).
Ni l'un ni l'autre n'est idéal, mais surtout pas un tas de statiques. Voici un exemple réel de mon expérience. Nous avons parlé à une base de données. Tout le monde a dit "il n'y en aura qu'un", donc quelqu'un a utilisé un singleton standard configuré par Spring. Ensuite, une nouvelle exigence a été ajoutée: pouvoir copier nos données dans une base de données autre (distante). Oops. Étant donné que nous avions un objet réel représentant la base de données, et qu'il s'agissait d'une fonctionnalité "rarement utilisée", j'ai pu le pirater en faisant une copie temporaire et en modifiant les champs et les valeurs, mais si cela avait été implémenté avec des statistiques globales, cela aurait été un vrai désastre.
D'après mon expérience, quand "ils" disent qu'il n'y aura qu'une seule base de données, un utilisateur, une application, une fenêtre principale, etc., "ils" ont tort. Avec un Singlton, vous avez au moins une chance de refactoriser et de le réparer.
Quelle est la différence entre toutes les méthodes statiques et l'application d'un modèle singleton?
Les deux ont le même effet: vous pouvez appeler une méthode de classe sans savoir comment obtenir une instance de la classe qui contient la méthode.
Cependant, si vous voulez implémenter des méthodes statiques Unittesting, c'est plus problématique car elles ne peuvent pas être facilement moquées .
Du point de vue des tests, il est plus facile de réécrire du code qui utilise des singeltons pour les rendre non testables avec des simulacres.
La soulution la plus flexible serait d'avoir Dependency_injection peu importe si vous utilisez un framework di-container (comme suggéré par @ Tazzy531) ou si vous câblez les dépendances par code.
J'espère que cela répondra juste à la question principale ici.
Il y a déjà peu de bonnes réponses dans SO . Je vais juste les citer.
Meilleure réponse, par Heinzi :
Un singleton est utilisé pour introduire une sorte d'état global dans une application. S'il est apatride, je ne vois pas non plus l'intérêt d'utiliser un singleton, sauf
- vous vous attendez à le prolonger avec état dans un avenir prévisible ou
- vous avez besoin d'une instance d'objet pour une raison technique particulière (par exemple, pour l'instruction C #
SyncLock
, bien que cela soit déjà assez farfelu) ou- vous avez besoin d'héritage, c'est-à-dire que vous voulez pouvoir remplacer facilement votre singleton par un autre en utilisant la même interface mais une implémentation différente. Par exemple, la méthode
Toolkit.getDefaultToolkit()
dans Java renverra un singleton dont le type exact dépend du système.
Haut commentaire pertinent, par back2dos :
(...) les singletons sont mal utilisés pour introduire des états mondiaux. Le but d'un singleton n'est pas de rendre un objet disponible globalement, mais de faire en sorte qu'un objet ne soit instancié qu'une seule fois. Les objets globaux sont un mal nécessaire. À moins que cela ne soit vraiment nécessaire, il faut essayer de ne pas les utiliser, car ils conduisent généralement à un couplage élevé, avec SomeSingleton.getInstance (). SomeMethod () partout.
tzaman a également écrit une bonne réponse:
Je pouvais voir un cas pour un singleton sans état utilisé à la place d'une classe de méthodes statiques, à savoir pour Dependency Injection .
Si vous avez une classe auxiliaire de fonctions utilitaires que vous utilisez directement, cela crée une dépendance cachée; vous n'avez aucun contrôle sur qui peut l'utiliser ou où. L'injection de cette même classe d'assistance via une instance singleton sans état vous permet de contrôler où et comment elle est utilisée, et de la remplacer/la simuler/etc. quand vous en avez besoin.
En faire une instance singleton garantit simplement que vous n'allouez pas plus d'objets du type que nécessaire (puisque vous n'en avez besoin que d'un seul).
Et enfin Sébastien s'est lui aussi très bien répondu:
En fait, j'ai trouvé une autre réponse non mentionnée ici: les méthodes statiques sont plus difficiles à tester.
Il semble que la plupart des frameworks de test fonctionnent très bien pour se moquer des méthodes d'instance, mais beaucoup d'entre eux ne gèrent pas de manière décente la simulation des méthodes statiques.
Cela étant dit, je conseille d'utiliser le modèle Toolbox .