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 PHP Discussion :

Bonne pratique POO : Où placer les fonctions communes ?


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut Bonne pratique POO : Où placer les fonctions communes ?
    Bonjour,

    En matière de bonne pratique en programmation objet, où placez-vous les fonctions utiles à plusieurs classes ?

    Par exemple, j'ai une fonction qui détermine l'année scolaire en cours en fonction de la date et j'ai besoin de cette fonction dans plusieurs contrôleur de l'application que je développe, et même potentiellement dans plusieurs modules.

    Serait-ce une bonne pratique de faire une classe générale Outils avec dedans les fonctions utiles à plusieurs endroits de l'application ?
    Ou bien un simple fichier PHP contenant les fonction et à inclure au besoin dans le code des contrôleurs qui en ont besoin ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  2. #2
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Si plusieurs classes partagent une ou plusieurs méthodes, tu peux utiliser les traits. Sinon un autre solution consiste à utiliser l'héritage, mais c'est moins souple car il faut que tes classes aient un ancêtre commun qui implémente la ou les méthodes (sans que ça devienne un non-sens total).

  3. #3
    Nb
    Nb est déconnecté
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 163
    Par défaut
    En terme de bonne pratique je ne sais pas trop.
    Perso j'aurais mis ca dans une classe AnneeScolaire en tant que methode statique. Classe qui pourrait par ailleurs posseder des methodes non statique plus tard dans le projet (calculer les dates des trimestres..etc).
    Si à aucun moment tu ne penses avoir besoins d objet AnneeScolaire alors mettre ca dans une bibliotheque de fonctions peut être aussi bien qu'une classe Outils.

    Pour les traits je pense que ca dépend, ca va forcément marcher, ca dépend du contexte. Par exemple si tu as besoins de l'année courante dans une classe Eleve, mettre la fonctionnalité dans un trait et faire un use dans Eleve va marcher, mais ca n'a aucun sens car ta classe éléve va "hériter" d'un comportement qui n'a aucun lien avec elle. Pas sur d'avoir ete tres clair là

  4. #4
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    Si plusieurs classes partagent une ou plusieurs méthodes, tu peux utiliser les traits. Sinon un autre solution consiste à utiliser l'héritage, mais c'est moins souple car il faut que tes classes aient un ancêtre commun qui implémente la ou les méthodes (sans que ça devienne un non-sens total).
    Niet pas d'héritage , sinon ça devient de l'héritage fonctionnel et c'est exactement ce qu'il faut éviter en POO.

    Pour moi la bonne pratique c'est la création de ce qu'on va appeler des "helpers". Ce sont des classes le plus souvent statique qui permettent d'encapsuler les fonctions "utilitaires" qui peuvent être utilisée un peu partout mais qui n'ont pas à faire partie d'autre classe sémantiquement parlant.

    Dans ton cas précis on pourrais imaginer un helper "date" dans lequel tu vas venir mettre toutes les fonctions utile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class DateHelper
    {
        public static function getCurrentScolarYear()
        {
            // Ton code
        }
    }
    Et partout où tu en as besoin tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $year = DateHelper::getCurrentScolarYear();
    Si ensuite tu à besoin de fonction pour faire des actions sur les chaines de caractères tu peux faire un helper "StringHelper" ou tu vas venir mettre tout ce qui te permet de traiter tes chaines partout dans ton code.
    Un exemple complet de helper sur les strings extrait de mon framework : https://github.com/grunk/Pry/blob/ma...il/Strings.php

    Tu répètes ensuite l'opération pour toutes les "catégories" de fonctions (string,date ...)
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre émérite Avatar de tdutrion
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2009
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 561
    Par défaut
    Je suis étonné de voir autant de personnes proposer une statique...

    Que ce soit les traits ou la statique, au moment de tester unitairement vos classes vous allez galérer...

    Pour moi la vraie "bonne pratique" dans ce cas est l'injection de dépendance.

    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
     
    interface CurrentScolarYearProvider 
    {
        public function getCurrentScolarYear() : ScholarYear;
    }
     
    final class DateHelper implement CurrentScolarYearProvider
    {
        public function getCurrentScolarYear() : ScholarYear
        {
            // Ton code
        }
    }
     
    final class MyController
    {
        private $helper;
     
        public function __construct(CurrentScolarYearProvider $helper)
        {
            $this->helper = $helper;
        }
     
        public function myAction()
        {
            return [
                'current_scolar_year' => $this->helper->getCurrentScolarYear(),
            ];
        }
    }
    Là, ton code est testable, et tu peux changer à la demande l'implémentation de ton provider.

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par tdutrion Voir le message
    Je suis étonné de voir autant de personnes proposer une statique...

    Que ce soit les traits ou la statique, au moment de tester unitairement vos classes vous allez galérer...
    Dans la réalité les gens qui on le temps et/ou le budget d'unit tester tout le code c'est une minorité. (perso je l'ai pas)
    Du coup les statiques ont du sens car il y'a beaucoup moins d'overhead qu'avec une injection de dépendance tout en gardant une organisation relativement propre.

    Peux tu détailler en quoi ca va être un problème au moment d'un test unitaire ? Si la classe statique est testée , on à pas besoin de la retester dans la classe qui l'utilise non ?
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre émérite Avatar de tdutrion
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2009
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 561
    Par défaut
    En fait tu as d'une part le problème de la statique dans le test, car ta statique va te donner disons "2017-2018" pour l'exemple, mais lorsque tu passes à l'année "2018-2019" ton test ne passera plus (car la valeur change, donc le résultat change).

    Si tu fais un test ou tu assert = date('Y') . '-' . (date('Y')+1), tu mets du code dans ton test, donc pas essence c'est faussé.
    Ce que tu veux savoir dans le test c'est "si j'entre avec 2017-2018, est ce que mon résultat contient bien cette valeur (transformée correctement). Du coup dans le cas du helper injecté tu peux facilement mocker la valeur.

    Pour le coup, selon ton framework l'injection ne rajoute pas massivement d'overhead, ni en charge de processing, ni en developpement, car tu auras l'autowiring qui s'occupe de ça (dans mon exemple il faut juste binder ton implementation à ton interface en fait)

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Merci pour vos avis.

    Citation Envoyé par CosmoKnacki
    Si plusieurs classes partagent une ou plusieurs méthodes, tu peux utiliser les traits.
    J'avais survolé la description des traits et n'avait pas perçu leur utilité.
    C'est souvent quand on est confronté à un problème qu'on comprend l'utilité de l'outil mystérieux qui traîne dans un coin.

    Citation Envoyé par grunk
    Pour moi la bonne pratique c'est la création de ce qu'on va appeler des "helpers".
    Quel serait l'avantage par rapport au trait ?
    La classe helper ne pourrait-elle pas être un trait ? N'est-ce finalement pas équivalent ?

    Citation Envoyé par tdutrion
    Pour moi la vraie "bonne pratique" dans ce cas est l'injection de dépendance.
    Qu'appelles-tu injection de dépendance ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    interface CurrentScolarYearProvider 
    {
        public function getCurrentScolarYear() : ScholarYear;
    }
    Je n'ai pas encore rencontré cette syntaxe avec le :.
    Ça veut dire quoi ?
    En plus, tu ne réutilise pas ScholarYear plus loin dans le code.

    En matière de test, j'essaie de tester mon code au fur et à mesure et de :
    - déboguer de suite ;
    - ou bien mettre des // FIXME ou // TODO pour déboguer ou améliorer plus tard.


    Je vais essayer les traits.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

Discussions similaires

  1. Bonnes pratiques : doit-on supprimer les listeners ?
    Par adiGuba dans le forum Général JavaScript
    Réponses: 22
    Dernier message: 31/07/2014, 07h38
  2. Où placer les fonctions matlab du file exchange
    Par takfa2008 dans le forum MATLAB
    Réponses: 3
    Dernier message: 07/04/2013, 21h44
  3. [POO] Question sur les fonctions
    Par Carb0 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 26/11/2008, 15h18
  4. [POO]Où placer les écouteurs d'évènement utilisateur?
    Par ChriGoLioNaDor dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 03/09/2008, 07h28
  5. [POO] Pb avec les fonctions xml et la POO
    Par QuantuX dans le forum Langage
    Réponses: 1
    Dernier message: 17/06/2006, 14h54

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