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 :

POO - Héritage - Singleton


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 66
    Points : 39
    Points
    39
    Par défaut POO - Héritage - Singleton
    Bonjour

    J'ai, pour le moment, 4 classes (pour résumer)

    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
    class Core {/*Pour le moment pratiquement vide, mais l'idée étant de mettre des fonctions utiles à tout le site tel que la vérification d'un éventuel mode maintenance ou pas */ }
     
    class Model extends Core {
    /*Contient la connexion à mysqli (pdo non autorisé pour le projet) 
    J'y ai également rajouté des fonctions pour vérifier automatiquement si les champs obligatoires sont bien remplis : */
    		protected function obligatoire($array = array(), $i = 0)  {
     
    			if(empty($array))
    				$array = $_POST['obligatoire'];
     
    			$i++;
    			if($i > 10)
    				return 'Erreur récursivité';
     
    			foreach ($array as $key => $value) {
    				if(is_array($value)) {
    					$deep = $this->obligatoire($value, $i);
    					if($deep !== true)
    						return $deep;
    				}
    				else {
    					if(empty($value) || $value ='')
    						return $key;
    				}
    			}
    			return true;
    		}
    }
     
    class Arbo extends Model {/*Récupère l'arbo depuis la base*/}
     
    class User extends Model {/*Inscription, profil ...*/}
    Le problème, si j'ai bien compris, c'est qu'au moment où je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    new Arbo();
    new User();
    J'instancie 2 fois la classe Core et la classe Model donc je définie 2 fois inutilement ma fonction obligatoire (et les autres)

    J'ai entendu parler des Singletons mais sans trop être sur de bien comprendre l'utilité et comment les utiliser. Pourriez vous m'expliquer comment organiser autrement mon code histoire d'éviter les utilisations superflues de mémoire ? Comment procéderiez vous pour organiser vos classes si vous étiez à ma place ?

    Merci d'avance pour vos éclaircissement

    Ps : j'ai lu plusieurs articles sur les Singletons et j'en ai vu des abstraits, des non abstrait, des étendus, des non étendus ... D'où ma confusion sur la meilleur utilisation dans mon cas.

    EDIT : Oups, un petit coup de phpinfo plus tard au cas où .... PHP Version 5.6.2

  2. #2
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Un vaste sujet que vous abordez là!
    Dans votre code initial vous faites de l'inversion de dépendance. Il semble que c'est un peu délicat pour vous, et je vous conseille donc de commencer par les bases et d'étudier également les patterns en PHP.
    Le singleton est une classe qui permet de n'instancier qu'une seule fois votre classe. En d'autres termes, vous ne pourrez avoir qu'une seule et même instance de votre classe singleton dans toute votre application. Ceci optimise en effet l'utilisation de la mémoire, à condition également de l'utiliser pour mettre en cache les données qui en dépendent et qui justifient une mise en cache.
    Lorsque vous utilisez un singleton comme contrôleur avec gestion de cache associé, je vous recommande de ne pas utiliser d'abstraction pour votre singleton (dans un usage général) sous peine de complexifier la gestion du cache d'une façon assez conséquente.
    Pour un singleton étendu, si la classe qu'il étends est aussi un singleton, il vous sera possible également d'accéder aux données que le singleton parent gère en cache.
    Maintenant pour ce qui est de savoir si vous avez besoin d'un singleton étendu ou abstrait, cela dépends de vos choix d'architecture applicative et de vos besoins applicatifs.

  3. #3
    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
    Si tu veux parler de l'héritage, ne te préoccupe pas de ça. PHP peut effectivement copier effectivement les méthodes d'une classe mère dans les classes filles, mais c'est la base même de la programmation par objets. L'impact de tout cela est négligeable et n'a aucune conséquence visible sur l'utilisation de la mémoire. Tu aurais une dizaine de classes qui se héritent les uns des autres que la différence ne se verra toujours pas dans les cadres d'utilisation de PHP.

    Si tu n'en veux pas, autant ne plus utiliser d'objets (ce qui serait ridicule), voire changer de langage.

    Bref, continue à faire de l'héritage, ne te préoccupe pas d'optimisations prématurées. Laisse le moteur de PHP s'en occuper pour toi.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 66
    Points : 39
    Points
    39
    Par défaut
    Merci pour vos réponses

    Le truc c'est que je n'ai pas forcément envie de tout laisser en plan et avoir, par exemple, 10 new classes extends Core (ce qui mettrait en mémoire toutes les méthodes & attributs de Core 10 fois) car si je crées un post sur le fofo, c'est aussi et surtout pour apprendre et m'améliorer . Je ne fais pas ça pour faire un site perso rapide mais développer étant mon métier (mais junior) j'aimerai autant prendre le temps de réfléchir correctement quitte à me prendre la tête pour pas grand chose (ça me servira toujours pour plus tard ! )

    Donc dans mon cas, il vaudrait mieux faire une série de singleton de type
    - Breadcrumb
    - Bdd (la connexion à pdo, histoire d'instancier une seule fois l'ouverture de connexion?)
    - Arbo

    Et en classes classiques les produits, catégories etc ?

    Les singletons ça n'est pas la même chose que les patterns ?

    Qu'appelez vous mise en cache des données ?

    Je dois filer, je continue de suivre le sujet merci et bonne soirée

  5. #5
    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
    Soit j'ai mal compris ton problème, soit tu ne m'as pas compris.

    - L'héritage fait partie du langage. PHP s'occupe très bien d'optimiser tout ça pour toi, tu n'a pas à t'en préoccuper. C'est la première fois que je vois quelqu'un ne pas vouloir utiliser l'héritage parce qu'elle consommerait trop de mémoire. Si tu cherches à ce point à économiser tes ressources, tu t'es trompé de langage. Fais du C ou de l'assembleur. Je répète: l'héritage est partie intégrante du langage, et donc tu n'a pas à t'en priver. C'est comme si tu disais; je ne vais pas utiliser une variable parce qu'une variable consomme de la mémoire. Si la classe B hérite de A, c'est que B doit avoir des méthodes/propriétés qui sont identiques à celle de A (sinon, l'héritage ne serait pas utile). Donc, si B a des méthodes identiques à A, mais tu veux absolument éviter l'héritage, ta solution serait la composition, qui consomme autant, sinon plus de ressources, ou bien le copier-collé, qui consomme encore plus de ressources, puisque le moteur de PHP ne peut plus faire les optimisations qu'il fait en cas d'héritage.

    - Le Singleton n'est pas du tout une alternative à l'héritage. C'est une tout autre technique (qui a d'ailleurs beaucoup de défauts) qui n'a rien à voir et qui est utilisé pour d'autres buts. L'alternative à l'héritage s'appelle la composition: c'est à dire qu'au lieu d'hériter d'une fonctionnalité X, tu "injectes" un objet possédant X dans ton objet. Mais ce n'est pas une alternative en termes d'usage mémoire etc... les deux font partie du langage, et le moteur de PHP fait toutes les optimisations nécessaires pour ça.

    - L'histoire de la connexion BDD en singleton, c'est une technique copiée bêtement à des langages comme Java ou .Net ou autres, mais qui n'a aucun intérêt avec PHP. En Java, tu as une application qui tourne en permanence sur le serveur. Il est donc utile de n'avoir qu'une seule connexion et de la réutiliser à chaque fois. Si on ouvre une nouvelle connexion par visiteur et que le site a 10000 visiteurs, on se retrouve avec 10000 connexions. Avec PHP, chaque processus est détruit à la fin d'une requête, il n'y a pas d'application qui réside en pérmanence en mémoire, donc quoi que tu fasses, tu auras toujours 10000 connexions si tu as 10000 visiteurs, singleton ou pas.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 66
    Points : 39
    Points
    39
    Par défaut
    Ok, merci pour ta réponse Tsilefy. Donc tu me confirme que si j'ai une classe mère A et que je fais

    new B;
    new C;
    new D;
    etc;

    qui sont toutes des filles de A, php va se débrouiller pour optimiser tout ça et ne pas bouffer toute la mémoire en chargeant 15 fois la classe A en mémoire ? C'est bon à savoir ça ! C'était ma crainte. Si tu confirme, mon problème est résolu . J'avais soudainement peur de faire n'importe quoi en partant sur cette solution

  7. #7
    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
    oui, PHP (et Java, et Python, et C++, et .Net, etc....) optimise tout ça de manière à ce que le coût soit négligeable comparé aux bénéfices obtenus. Si tu veux savoir comment PHP fait (et plus généralement comment PHP traite les objets et classes, lis cet article extrêmement intéressant de Julien Pauli (warning: en anglais), notamment la partie "Class binding".

    Pour simplifier:
    - PHP vérifie si une classe hérite d'une autre classe
    - Si oui, PHP copie les méthodes et propriétés de la classe mère dans la classe fille.
    - Mais attention, "copier" est ici au sens de PHP. Ce n'est pas une copie physique, c'est juste une incrémentation du compteur de référence (refcount) de la méthode, propriété ou constante de la classe mère (pour vraiment simplifier, à chaque fois qu'une classe hérite d'une autre classe, PHP ajoute +1 à chaque compteur.
    - conclusion: l'héritage (et l'implémentation d'interface) ne coûte rien en termes de mémoire, mais a un coût en termes de processeur. Coût négligeable, je te rassure, sauf si tu fais de l'informatique embarquée (mais dans ce cas, PHP n'est pas le bon langage).

  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
    Maintenant, si tu 15 classes qui héritent d'une classe mère, ça veut dire que tu as un sérieux problème de conception, et que ta classe A fait trop de chose. Une classe ne doit avoir qu'une seule responsabilité à la fois, et ta classe A a trop de responsabilités. Il vaut mieux la séparer en plusieurs petites classes.

  9. #9
    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
    Typiquement l'héritage de Core ressemble fortement à de l'héritage fonctionnel ce qu'il faut évite au maximum. (Core et model n'ont pas de lien direct si ce n'est récupérer une fonction).

    Core devrait plutôt être une classe avec des méthode statique accessible par les modèle plutôt qu'un héritage à la vue de la description que tu en fait
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Pour répondre à tes questions:
    1) Le singleton EST un pattern.
    2) La mise en cache des données permets de persister des variables entre deux requêtes http pour éviter de les requêter en DB à chaque nouvelle requête sur le serveur.

    ++

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 66
    Points : 39
    Points
    39
    Par défaut
    Merci pour vos réponses ! Oui lorsque je disais 15 classes héritant de A, c'était pour le principe de fonctionnement, ce n'est pas ce que je comptais faire. Merci pour ton lien et ton explication Tsilefy !

    Effectivement aussi, Core ne me servait à rien pour le moment mais j'avais l'impression que les framework POO (prestashop, codeIgniter) avaient toujours un controller "racine" dont héritait tout le reste.

    Finalement je vais retirer Core je pense (ou au moins virer l'héritage entre Model et Core qui, effectivement, n'ont rien à faire entre eux). J'ai créé un singleton avec des méthodes static pour gérer les erreurs, ce qui me permet n'importe où de faire, par exemple : Message::setMessage('Il faut vous inscrire blabla'). Et je laisse mes contôles de input/output en base dans la classe mère Model.
    C'est une bonne pratique du coup ? Et je laisse mes contôles de input/output en base dans la classe mèr Model

    Tse_jc, je n'ai jamais créé de cache coté php (je ne savais pas que c'était possible). Par contre pour les rares données qui ne changent pas (l'arborescence par exemple) je les charges en $_SESSION pour éviter d'interroger la bdd à chaque changement de page... C'est mal ? ^^

  12. #12
    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 Xenofexs Voir le message
    J'ai créé un singleton avec des méthodes static pour gérer les erreurs, ce qui me permet n'importe où de faire, par exemple : Message::setMessage('Il faut vous inscrire blabla'). Et je laisse mes contôles de input/output en base dans la classe mère Model.
    C'est une bonne pratique du coup ? Et je laisse mes contôles de input/output en base dans la classe mèr Model
    Tant que ton singleton ne concerne pas des fonctions essentielles, ce n'est pas grave.

    Un jour, quand tu apprendras les tests unitaires, tu comprendras pourquoi il faut virer les singletons et les statiques :-)

  13. #13
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Tse_jc, je n'ai jamais créé de cache coté php (je ne savais pas que c'était possible). Par contre pour les rares données qui ne changent pas (l'arborescence par exemple) je les charges en $_SESSION pour éviter d'interroger la bdd à chaque changement de page... C'est mal ? ^^
    En PHP la persistence se gère avec $_SESSION. Par contre en développement orienté objet, il faut préserver l'encapsulation. Faire un contrôleur en singleton c'est bien mais la gestion de la persistence des variables qu'il doit gérer ne doit pas être externalisée. Gérer un cache avec ton contrôleur revient à pouvoir sérialiser/désérialiser ta classe contrôleur en $_SESSION.

    J'ai crée un singleton avec des méthode statiques
    Des méthodes statiques n'ont rien à faire dans un singleton. Si vous pensez le contraire, vous devriez repenser votre besoin d'utiliser un singleton.

    Un jour, quand tu apprendras les tests unitaires, tu comprendras pourquoi il faut virer les singletons et les statiques :-)
    Sans rentrer dans la polémique, le test fonctionnel est bien plus constructif et nécessaire que le test unitaire. Mais c'est un autre débat qui n'a pas de raison d'être ici.

    Bon week-end.

Discussions similaires

  1. [POO] héritage en php
    Par zana74 dans le forum Langage
    Réponses: 3
    Dernier message: 09/08/2006, 09h50
  2. [POO] Héritage vs classe dans une classe
    Par robichou dans le forum Langage
    Réponses: 4
    Dernier message: 06/08/2006, 23h51
  3. [POO] Poo : héritage & constructeur
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 11/07/2006, 14h29
  4. [POO]héritage du constructeur de la classe parente
    Par new_wave dans le forum Langage
    Réponses: 7
    Dernier message: 10/03/2006, 14h25
  5. [POO-Héritage] Appel du constructeur en PHP4.3.2
    Par raoulchatigre dans le forum Langage
    Réponses: 4
    Dernier message: 28/11/2005, 15h37

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