IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Cas d'utilisation Singleton?


Sujet :

avec Java

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 176
    Points : 99
    Points
    99
    Par défaut Cas d'utilisation Singleton?
    Bonjour à tous.
    Dans quel cas utiliser un Singleton?
    Je sais que ça permet de créer une seul instance de class, mais je ne vois pas de cas concret d'utilisation.

    Peut-on l'utiliser dans le cas du modèle MVC, mon contrôleur peut-il être instancier comme un Singleton?
    Ma classe qui me sert de connection à une DB, peut-elle instancier comme Singleton?

    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import javax.swing.JOptionPane;
     
    /**
     * Class ConnectDAO pour me connecter à ma DB.
     *
     * @author Fred
     */
    public class ConnectDAO {
     
        private final String urlDB;
        private final String passwordDB;
        private final String userDB;
        private static Object INSTANCE;
     
        //*******************Constructeur********************************************
        public ConnectDAO() {
            this.userDB = "xxxx";
            this.passwordDB = "xxxx";
            this.urlDB = "localhost:3306/vente_articles?useLegacyDatetimeCode=false&serverTimezone=Europe/Brussels";
     
        }
     
        /**
         * getInstance, crée une instance unique de ConnectDAO et renvoie cet instance.
         * @return 
         */
        public static ConnectDAO getInstance() {
            if (ConnectDAO.INSTANCE == null) {
                INSTANCE = new ConnectDAO();
            }
            return (ConnectDAO) INSTANCE;
        }
     
        public Connection connection() throws SQLException {
            Connection con;
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
                con = DriverManager.getConnection(("jdbc:mysql://") + this.urlDB, this.userDB, this.passwordDB);
                return con;
            } catch (ClassNotFoundException ex) {
                JOptionPane.showMessageDialog(null, "Erreur driver mysql: " + ex);
                return null;
            }
     
        }
     
    }

  2. #2
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Bonsoir,

    Il faut savoir que le Singleton n'est rien d'autre conceptuellement qu'une variable globale déguisée (mais sur lequel contrairement à une variable globale, on peut gérer les accès concurrents de manière intrinsèque grâce à l'encapsulation).
    A fuir le plus possible car rendant global un état qui pourrait être modifié, soit à plusieurs endroit du programme (ce qui le rend quasi intestable), soit par plusieurs Thread/Process (ce qui pose des problèmes d'accès concurrents).

    Pour les exemples d'utilisation :
    • la gestion d'un cache est souvent implémentée sous forme de singleton. Par exemple dans un logiciel de jeu, on va avoir un ResourceManager qui va charger les ressources (texture, mesh, scénario du niveau...) à partir d'un fichier (local ou distant). Les accès disques/réseaux sont couteux, on met donc en cache les données lues pour éviter de le refaire.


    • les contrôleurs HTTP, sont aussi parfois des singletons par besoin de performance. La création d'un objet ayant un coût (variable selon les langages, en Java, c'est assez rare d'utiliser un Singleton pour un contrôleur HTTP, on utilise d'autres mécanismes), ça peut-être nécessaire (mais on évitera dans la mesure du possible d'avoir un état au sein du singleton).


    A noter que ce genre d’optimisation ne doit jamais être fait avant d'avoir rencontré et localisé un soucis de performance sur la partie du code en question.
    premature optimization is the root of all evil-- DonaldKnuth
    qu'on pourrait traduire par : l'optimisation prématurée est à l'origine de tous les maux.

    Dans le cas que vous proposez, l'utilisation d'un singleton pour gérer une connexion BDD, pose un problème. Votre application utilisera une seule connexion BDD.
    S'il s'agit d'une application standalone, ça ne posera pas de problème.
    S'il s'agit d'un webservice, tous les utilisateurs se retrouveront à utiliser la même connexion à la BDD, ce qui causera un goulot d'étranglement car les traitements seront effectués en série (un client devant attendre que le précédent ait complété sa requête). Généralement on utilisera ce qu'on appel un pool (groupe) de connexions (créées au démarrage de l'application ou à la demande), dimensionné en fonction du besoin, qui seront réutilisées.

    Je viens de voir que votre DAO ne stock pas la connexion (ce qui évite le goulot d'étranglement mentionné plus haut mais perd la main sur le nombre de connexions créées). Dans le contexte, vous ne gagnez rien à remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bddConnection = new ConnectDAO().connection()
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bddConnection = ConnectDAO().getInstance().connection()
    Vous complexifiez inutilement le code et vous introduisez un état global qui comme dit plus haut rend l'application plus compliquée à tester.

    Une remarque sur votre code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      JOptionPane.showMessageDialog(null, "Erreur driver mysql: " + ex);
    Ce type de code n'a rien à faire dans votre DAO. Celui-ci n'est pas censé savoir qu'il est utilisé au sein d'une application SWING.
    En faisant ça, non seulement vous mélanger au même endroits des notions qui n'ont rien à voir (gestion BDD et de l'UI), mais en plus votre DAO ne pourra pas être réutilisé dans une application qui n'aurait pas d'interface graphique (ou qui utiliserai une interface Web). Vous devez remonter l'erreur à l'appelant qui s'il est légitime la traitera (sinon la remontera à son appelant etc).

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 176
    Points : 99
    Points
    99
    Par défaut
    Merci pour vos explications, j'y vois plus clair.
    Ici il s'agit d'une connexion à une DB local pour apprendre (opération CRUD).

    Pour le code ci-dessous, je ne compte pas laisser cette DialogBog à cet endroit.
    Quand je ferai mes vues, elle sera déplacée dans celles-ci.

    Par contre je galère pas mal sur la gestion d'erreur, surtout dans les tests unitaires.
    Je vais probablement faire un nouveau post sur le forum sur ce sujet.

    Une remarque sur votre code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      JOptionPane.showMessageDialog(null, "Erreur driver mysql: " + ex);
    Ce type de code n'a rien à faire dans votre DAO. Celui-ci n'est pas censé savoir qu'il est utilisé au sein d'une application SWING.
    En faisant ça, non seulement vous mélanger au même endroits des notions qui n'ont rien à voir (gestion BDD et de l'UI), mais en plus votre DAO ne pourra pas être réutilisé dans une application qui n'aurait pas d'interface graphique (ou qui utiliserai une interface Web). Vous devez remonter l'erreur à l'appelant qui s'il est légitime la traitera (sinon la remontera à son appelant etc).[/QUOTE]

Discussions similaires

  1. [Modélisation] Maille des cas d'utilisation
    Par ftrifiro dans le forum Cas d'utilisation
    Réponses: 14
    Dernier message: 28/08/2005, 18h39
  2. Cas d'utilisation, quel niveau de détails
    Par Celelibi dans le forum Cas d'utilisation
    Réponses: 5
    Dernier message: 20/02/2005, 20h16
  3. [Modélisation] Cas d'utilisation et acteurs
    Par ftrifiro dans le forum Cas d'utilisation
    Réponses: 5
    Dernier message: 30/01/2005, 15h20
  4. cas d'utilisation
    Par Yveke dans le forum Cas d'utilisation
    Réponses: 7
    Dernier message: 23/12/2004, 10h27
  5. [corba] débutant : dans quels cas l'utiliser
    Par jmturc dans le forum CORBA
    Réponses: 2
    Dernier message: 10/10/2002, 08h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo