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 :

Conception POO méthode de classe déclarée forcément dans une interface


Sujet :

Langage PHP

  1. #1
    Membre averti Avatar de mapmip
    Profil pro
    ulla
    Inscrit en
    Juillet 2006
    Messages
    1 315
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ulla

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 315
    Points : 345
    Points
    345
    Par défaut Conception POO méthode de classe déclarée forcément dans une interface
    Salut,

    dans PHP ou tout autre langage POO,
    pensez vous que ca soit une bonne facon de concevoir les classes de la facon suivante :
    une classe normale ou abstraite ne doit pas déclarer directement une méthode en son sein,
    la méthode doit d'abord être déclarée dans une interface puis la classe implémente l'interface et la méthode en question.

    Merci d'avance

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Pas nécessairement. Une interface est nécessaire lorsque tu peux avoir plusieurs implémentations possibles. Il y a des cas où c'est rarement le cas, comme les value objects ou les data transfer objects; d'autres où ce n'est jamais le cas, par exemple les classes anonymes.

    De plus, une interface est juste une... interface, c'est-à-dire un dispositif pour les objets externes d'accéder à une "famille" d'objet. Mais un objet peut aussi avoir des méthodes propres.

    De manière générale, il ne faut pas essayer de tout prévoir à l'avance (et se dire: peut-être qu'un jour j'aurais besoin d'objets similaires et je dois m'y préparer en créant une interface) parce qu'on ne peut pas tout prévoir justement et que les contraintes du futur sont imprévisibles. Si tu n'as pas besoin de multiples implémentations, déclare directement tes méthodes dans la classe; il sera toujours temps de refactoriser plus tard.

  3. #3
    Membre averti Avatar de mapmip
    Profil pro
    ulla
    Inscrit en
    Juillet 2006
    Messages
    1 315
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ulla

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 315
    Points : 345
    Points
    345
    Par défaut
    Citation Envoyé par Tsilefy Voir le message
    Une interface est nécessaire lorsque tu peux avoir plusieurs implémentations possibles .
    Que veux tu dire par implémentations ? Plusieurs méthodes qui portent le même nom voire même nombre et type d'argument mais de classes différentes ?

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Prend l'exemple d'un code dont le but est d'enregistrer des logs par exemple.

    Tu peux vouloir enregistrer des logs dans un fichier, dans une base de données , dans un syslog, dans un greylog , etc ...
    Ca veux dire que tu vas à voir autant de classe que destination (on va appeler ca des writers).

    A un moment donner tu vas instancier un objet du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $logs = new Logs('file'); // Pour écrire dans un fichier
    //$logs = new Logs('bdd'); // Pour écrire dans une base
    $logs->write('Mon message'); // Quelque soit le type , la fonction est la même
    Pour que ce soit transparent , il faut que tes writers implémentent tous la fonction write(). Et pour imposer ca , c'est l'interface qui entre en jeu.

    Le but de l'interface c'est donc d'imposer un "contrat" aux classes qui l'implémente. Il y'a une vraie signification derrière son utilisation.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre émérite
    Avatar de gene69
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 769
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 769
    Points : 2 446
    Points
    2 446
    Par défaut
    effectivement, soit tu passes par une interface et ton code verifies le type interface, soit par une classe abstraite.

    l'avantage de l'interface c'est que tu as la possibilité d'en avoir plusieurs implémentée dans la meme classe.
    l'avantage de la classe (mère abstraite ou pas) c'est que tu as possibilité de réutiliser du code parent ... mais qu'un seul parent.

    Avant je préfèrai les classes mère, maintenant c'est plus interface.

    Quand aux traits... j'ai peu eu affaire à eux.

    C'est l'éternelle question de la POO. seule l'expérience peu t'aider.
    PHP fait nativement la validation d'adresse électronique .
    Celui qui a inventé mysql_connect(...) or die() est déjà mort plusieurs fois.

    Utilisez le bouton résolu!

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par gene69 Voir le message

    Avant je préfèrai les classes mère, maintenant c'est plus interface.
    Pareil, ça fait des années que je n'utilise plus l'héritage sauf contraint et forcé. Je ne vois aucun cas dans lequel l'héritage est la meilleure solution, c'est juste du copier-coller qui ne dit pas son nom (et qui prête donc à confusion, surtout les débutants). Je préfère une interface, la composition. Quite à utiliser du copier-coller, mieu vaut utiliser les traits qui eux au moins sont clairs (même si la composition résout mieux ces problèmes).

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    L'héritage et l'interface sont deux choses bien distinctes et on chacune leur intérêt.

    Une interface impose un fonctionnement que l'on va être obliger d'implémenter. Un héritage permet de dire qu'un objet fait partit d'un ensemble sans pour autant forcer son comportement.

    L’héritage permet de dire l'objet X est quelque chose
    L'interface permet de dire l'objet X peut faire quelque chose

    C'est une nuance qui à son importance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    interface Reparaible
    {
        public diagnostic();
    }
    class Vehicle{
        public $brand;
        public $model;
    }
     
    class Bus extends Vehicle{}
     
    class Car extends Vehicle implements Repairable {}
    Dans cet exemple je sais que Bus et Car sont tous deux des Vehicle , qui vont avoir des propriétés communes (marque, model , ...).
    Je ne sais pas ce que Bus peut réellement faire. Il aura les même capacité de base que n'importe quel Vehicle mais j'en sais pas plus.
    En revanche je suis certains que si j'ai une instance de Car, je pourrais faire un diagnostic() dessus car je contraint son comportement via une interface.

    Là ou ca devient un peu plus compliqué c'est quand on hérite d'une classe abstraite. On mélange les deux mondes

    L'erreur très courante c'est de faire de l'héritage fonctionnelle (hériter pour avoir une fonctionnalité d'une classe) sans qu'il y'est de sens derrière cet héritage. C'est une erreur de conception grossière mais malheureusement très courante ...
    Dans mon exemple ca serait par exemple avoir une classe Chien qui hérite de Vehicle parce que elle à une méthode avancer() qui m’intéresse.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    J'opposais plutôt héritage et interface/composition, désolé si je n'ai pas été clair.

    Mon problème avec l'héritage c'est justement le cas de ton exemple: "Véhicle" n'existe pas concrètement. C'est une abstraction qui nous permet de regrouper des marques, modèles et types différents. Tous les Vehicles se counduisent (donc ont une fonction drive()), mais ne se conduisent pas de la même manière. Tu as donc des leaky abstractions, malgré l'héritage. Autant ne pas l'utiliser et manipuler directement la classe concrète, à moins d'avoir des bénéfices très concrets (que ni la composition par objets, ni la composition par traits ne peuvent apporter).

  9. #9
    Membre émérite
    Avatar de gene69
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 769
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 769
    Points : 2 446
    Points
    2 446
    Par défaut
    à la reflexion, j'utilise des interfaces dans toutes les classes réutilisables ailleurs sur la bordure du "namespace" par exemple si j'avais un jeu de classes pour traiter des bases oracles et du business spécifique à de la base oracle, tout ce qui est sur la ligne de démarcation entre mes classes oracle et les classes spécifique à l'outil, ça se retrouverait dans des interfaces, par contre tout le reste c'est sutout de l'héritage.

    bref je n'écris jamais des trucs compliqués avec des traits moi
    PHP fait nativement la validation d'adresse électronique .
    Celui qui a inventé mysql_connect(...) or die() est déjà mort plusieurs fois.

    Utilisez le bouton résolu!

  10. #10
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    bref je n'écris jamais des trucs compliqués avec des traits moi
    Pareil pour moi. J'ai joué au début quand c'est arrivé, mais à la réflexion la composition est plus facile à lire et à comprendre!

Discussions similaires

  1. Réponses: 6
    Dernier message: 18/02/2015, 09h30
  2. Réponses: 5
    Dernier message: 28/11/2014, 14h46
  3. Comment récupérer une variable déclarée GLOBALE dans une classe PHP
    Par Globolite dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 08/03/2013, 13h41
  4. Réponses: 3
    Dernier message: 09/04/2008, 17h45
  5. Réponses: 3
    Dernier message: 05/10/2006, 18h52

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