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

Langage Java Discussion :

Bon usase de fonctions static ou de singleton


Sujet :

Langage Java

  1. #1
    Membre éprouvé Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Points : 1 014
    Points
    1 014
    Par défaut Bon usase de fonctions static ou de singleton

    J'ai une question par rapport à quelle est la bonne pratique et quelle est la mauvaise pratique et pourquoi ?

    Supposons que je veuille réaliser une "bibliothèque" de fonctions (pour l'exemple on dira les fonctions addition et soustraction d'entiers).

    Première solution :
    Je réalise une classe qui contient mes deux fonctions déclarées en static :
    Code JAVA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MathUtils {
     
        public static int add(int a, int b) {
            return a+b;
        }
     
        public static int sub(int a, int b) {
            return a-b;
        }
    }

    Deuxième solution :
    Je réalise un singleton pour qui contient mes deux fonctions :
    Code JAVA : 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
    public class MathUtils {   
        private MathUtils() {}
     
        private static MathUtils INSTANCE = new MathUtils();
     
        public static MathUtils getInstance() {
            return INSTANCE;
        }
     
        public int add(int a, int b) {
            return a+b;
        }
     
        public int sub(int a, int b) {
            return a-b;
        }
    }

    Mon avis : J'ai l'impression que c'est deux implémentation sont équivalentes (à part peut-être en terme de performance et de compilation). Je trouve donc juste l'utilisation d'un singleton plus "lourd" (=plus de code pour résultat équivalent). J'utiliserais donc plutôt la première solution.

    Mais je me pose quand même ces questions :
    1. Y a-t-il une différence de performance entre ces deux solutions ?
    2. ]Quelle est la bonne pratique (=la solution la plus "java") ?
    3. Pourquoi l'autre n'est pas une bonne pratique ? Dans quels cas alors l'utiliser ?
    4. Dans la première solution, faut-il déclarer la class comme static et/ou abstract ? et pourquoi ?
    5. Est-ce que j'ai tout faux est la bonne solution est aucune de celles proposées ?
    "On sera toujours mieux installé assis en 1ère que debout en 2nde", un illustre inconnu


    Avant de poser une question vérifiez si elle n'a pas déjà une réponse dans les cours et tutoriels
    Si votre problème est pensez à marquer la conversation comme telle
    Si un message est utile, pertinent, et/ou vous êtes d'accord avec, pensez à à l'inverse s'il est inutile, faux ou que vous n'êtes pas d'accord, pensez à

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hello,

    Citation Envoyé par Drowan Voir le message
    Y a-t-il une différence de performance entre ces deux solutions ?
    Rien qui justifie d'en tenir compte pour choisir l'une ou l'autre.

    Citation Envoyé par Drowan Voir le message
    Quelle est la bonne pratique (=la solution la plus "java") ?
    En théorie la solution la plus "objet", et donc quelque part, "java", est de ne jamais avoir aucune méthode static non-private. Toute méthode "visible" doit être fournie par un objet en fonction de sa classe, pas directement par une classe.

    Mais seul un Sith raisonne dans l'absolu.

    Dans la réalité ce raisonnement objet découle des avantages qu'on en tire : une plus grande flexibilité, du fait de pouvoir choisir / redéfinir l'implémentation des méthodes offertes. Cela permet par exemple de proposer différentes stratégies pour offrir "en apparence" le même service, en fonction des besoins. Genre un stockage de données qui utiliserait soit une base de données, soit l'enregistrement sur disque, soit ne pas réellement stocker les objets et les garder juste en mémoire.

    Cette flexibilité permet aussi de faire plus facilement des tests unitaires. Genre quand on veut tester une classe qui va utiliser ton service, on veut tester cette classe et qu'elle appelle le service correctement, on ne veut pas tester le service lui-même, qui sera testé unitairement avec d'autres tests qui se concentrent sur lui seulement. Il est alors possible de fournir à la place de ce service, un service fantoche qui implémente les mêmes méthodes et peut être appelé pareil, mais en réalité il ne fait que ce que le code de test lui dit de faire, et il permet de vérifier si oui on non il a été appelé et si oui, comment. Permettant donc de vérifier qu'il a été utilisé correctement. A part ça il ne fait rien. C'est comme ça qu'on fait des tests unitaires.

    Cette flexibilité, la programmation objet, n'est permise que par la deuxième façon de faire, et elle est en général préférée.

    Mais parfois vouloir cette flexibilité est un peu idiot. Par exemple dans le cas où on veut additionner ou soustraire deux nombres. Une addition c'est une addition. Il n'y a qu'une seule manière de le faire, et c'est tellement vrai qu'on ne veut même pas permettre de faire autrement. Disons que c'est un concept basique et universel, qui ne devrait pouvoir être fait que d'une façon, et dont le fait de passer dedans fait partie intégrante de ce qu'on veut tester dans les classes qui s'en servent.
    Et accessoirement, faire à la méthode objet correctement, demande un certain travail supplémentaire (il vaut mieux utiliser une interface et l'implémenter, que juste faire une classe).
    Lorsque c'est acceptable, une classe qui ne fournit que des méthodes statiques, donne moins de travail et l'emploi en est plus simple.
    On appelle ça une classe utilitaire.

    C'est là que devrait résider la décision. Est-ce que les méthodes que je veux fournir au reste du programme, ont l'air naturellement de se résumer à une classe utilitaire ? Ou est-ce que ça ressemble plutôt à un service, plus ou moins configurable, plus ou moins interchangeable ? Par exemple s'il y a le moindre besoin que les méthodes offertes "connaissent" un paramètre qui a été réglé au démarrage et dont ce serait "lourd" de le passer à chaque appel, genre le nom de la partie d'un jeu, alors ça ne colle pas avec une classe utilitaire.

    Des classes utilitaires il y en a dans Java, par exemple la classe Math qui fournit les fonctions mathématiques. Également Collections et Arrays, qui offrent des traitements assez évidents sur les Collections ou les tableaux.

    Citation Envoyé par Drowan Voir le message
    Pourquoi l'autre n'est pas une bonne pratique ? Dans quels cas alors l'utiliser ?
    Voir réponse au-dessus.

    Citation Envoyé par Drowan Voir le message
    Dans la première solution, faut-il déclarer la class comme static et/ou abstract ? et pourquoi ?
    Une classe ne peut être static que si elle est à l'intérieur d'une autre classe, donc déjà, pas static, non.
    Déclarer une classe abstract signifie que sa vocation est d'être étendue par des sous-classes qui, elles, finiront par ne pas être abstract. Ce n'est pas le cas ici, elle ne doit pas être étendue. Donc pas abstract, non.

    Par contre comme par nature elle ne doit pas être étendue, on peut la déclarer final, pour empêcher qu'elle le soit.
    Et comme par nature il ne doit pas en exister d'instance, ça peut être intéressant de lui donner un constructeur privé qui ne fait rien et n'est jamais appelé. Cela empêchera les autres classes d'essayer d'appeler un constructeur et donc ainsi il n'y en aura jamais d'instance.

    Citation Envoyé par Drowan Voir le message
    Est-ce que j'ai tout faux est la bonne solution est aucune de celles proposées ?
    Non, c'est une question de conception très légitime et je dirais même assez fascinante.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éprouvé Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Points : 1 014
    Points
    1 014
    Par défaut
    Déjà merci d'avoir pris le temps de me répondre T'as réponse est super intéréssante et réponds bien à toutes mes questions

    Citation Envoyé par thelvin Voir le message
    C'est là que devrait résider la décision. Est-ce que les méthodes que je veux fournir au reste du programme, ont l'air naturellement de se résumer à une classe utilitaire ? Ou est-ce que ça ressemble plutôt à un service, plus ou moins configurable, plus ou moins interchangeable ? Par exemple s'il y a le moindre besoin que les méthodes offertes "connaissent" un paramètre qui a été réglé au démarrage et dont ce serait "lourd" de le passer à chaque appel, genre le nom de la partie d'un jeu, alors ça ne colle pas avec une classe utilitaire.
    Je retiens surtout ce paragraphe qui explique comment prendre la décision entre les deux solutions.

    Des classes utilitaires il y en a dans Java
    C'est bien ce qu'il me semblait. C'était aussi une raison pourquoi je pensais la solution 1 meilleure car je l'avais déjà vu dans Java même.

    Une classe ne peut être static que si elle est à l'intérieur d'une autre classe, donc déjà, pas static, non.
    Très juste, merci de le rappeler

    Déclarer une classe abstract signifie que sa vocation est d'être étendue par des sous-classes qui, elles, finiront par ne pas être abstract. Ce n'est pas le cas ici, elle ne doit pas être étendue. Donc pas abstract, non.
    C'est toujours un concept que je trouve pas naturel les classes abstraites. A chaque fois j'ai besoin de réfléchir à nouveau pourquoi un classe abstraite plutôt qu'une interface ou qu'une super classe normale Mais je fini toujours pas retrouver la raison

    Par contre comme par nature elle ne doit pas être étendue, on peut la déclarer final, pour empêcher qu'elle le soit.
    Et comme par nature il ne doit pas en exister d'instance, ça peut être intéressant de lui donner un constructeur privé qui ne fait rien et n'est jamais appelé. Cela empêchera les autres classes d'essayer d'appeler un constructeur et donc ainsi il n'y en aura jamais d'instance.
    Bien vu, je retiens ça pour les prochaines fois

    Non, c'est une question de conception très légitime et je dirais même assez fascinante.
    Merci #GloirePersonnelle
    "On sera toujours mieux installé assis en 1ère que debout en 2nde", un illustre inconnu


    Avant de poser une question vérifiez si elle n'a pas déjà une réponse dans les cours et tutoriels
    Si votre problème est pensez à marquer la conversation comme telle
    Si un message est utile, pertinent, et/ou vous êtes d'accord avec, pensez à à l'inverse s'il est inutile, faux ou que vous n'êtes pas d'accord, pensez à

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre éprouvé Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Points : 1 014
    Points
    1 014
    "On sera toujours mieux installé assis en 1ère que debout en 2nde", un illustre inconnu


    Avant de poser une question vérifiez si elle n'a pas déjà une réponse dans les cours et tutoriels
    Si votre problème est pensez à marquer la conversation comme telle
    Si un message est utile, pertinent, et/ou vous êtes d'accord avec, pensez à à l'inverse s'il est inutile, faux ou que vous n'êtes pas d'accord, pensez à

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ugh, quelle abomination.

    Faut-il manquer de confiance en soi en tant que programmeur/professionnel du logiciel, pour estimer avoir besoin de détourner la notion de type énuméré pour faire des singletons.

    Soit dit en passant, la notion même de faire des "vrais singletons", c'est-à-dire garantir qu'il y a une instance et qu'il ne peut y en avoir qu'une seule, en lieu et place de juste prévoir qu'en pratique on n'aura probablement pas besoin de plus d'une instance, est déjà en soi le révélateur d'un sérieux problème de conception. On devrait clairement n'en avoir rien à cirer, de si c'est vraiment un singleton ou pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre éprouvé Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Points : 1 014
    Points
    1 014
    Par défaut
    Citation Envoyé par thelvin Voir le message
    On devrait clairement n'en avoir rien à cirer, de si c'est vraiment un singleton ou pas.
    Je peux me tromper mais je suis pas vraiment d'accord.

    Je pense qu'il y a deux approches :
    • Smart user : On considère que mon modèle est bien conçu et que l'utilisateur est inetlligent et va faire comme expliqué. Dans ce cas effectivement ce n'est pas très important de s'assurer que le singleton en est vraiment un. Puisque on va l'utiliser exactement comme prévu.
    • Full secure : On prend aucun risque d'erreur de conception ou de mauvaise utilisation par l'utilisateur en s'assurant que le singleton soit parfaitement unique et accessible uniquement comme souhaité.

    (J'ai inventé les noms smart user et full secure, je les trouvais bien c'est tout. Cherchez pas une référence à un bouquin ou une théorie )
    "On sera toujours mieux installé assis en 1ère que debout en 2nde", un illustre inconnu


    Avant de poser une question vérifiez si elle n'a pas déjà une réponse dans les cours et tutoriels
    Si votre problème est pensez à marquer la conversation comme telle
    Si un message est utile, pertinent, et/ou vous êtes d'accord avec, pensez à à l'inverse s'il est inutile, faux ou que vous n'êtes pas d'accord, pensez à

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Sauf que ça n'a rien à voir avec de la sécurité.

    Un singleton c'est quelque chose dont on se dit, "oh, dans mon application, je n'en utiliserai qu'un". Quand on se dit autre chose que ça, on a déjà échoué. Il fallait faire autrement, ça n'a rien à voir avec singleton ou pas singleton.

    Et le truc, c'est que peut-être aujourd'hui il n'en faut qu'un dans l'application, mais demain il en faudra trois différents pour trois systèmes différents du programme. Notamment au moment d'en automatiser les tests.

    Si l'utilisateur trouve le moyen d'en faire une autre instance, déjà il a quand même sérieusement cherché, ce n'est absolument pas un accident. Ensuite, ce n'est pas bien grave. Si ça ne fait pas ce que ça doit ça se verra tout de suite, et le fait qu'on a plusieurs instances quand on croyait n'en avoir qu'une sera évident au débuggeur et au profiler.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 22/12/2006, 11h35
  2. [C#] Appel d'une fonction static impossible ?
    Par TheParadoX dans le forum Windows Forms
    Réponses: 2
    Dernier message: 17/08/2006, 10h23
  3. fonction static dans une class
    Par Stany dans le forum C++
    Réponses: 3
    Dernier message: 16/06/2006, 14h43
  4. Définition d'une fonction static ?
    Par tintin72 dans le forum C++
    Réponses: 9
    Dernier message: 22/12/2005, 11h50
  5. Réponses: 3
    Dernier message: 15/12/2005, 22h04

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