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] Structure


Sujet :

Langage PHP

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 35
    Par défaut [POO] Structure
    Bonjour à tous,

    Je me suis mis à lire divers tutoriels sur la POO il y a quelques jours. J'ai également le livre PHP 5 Avancé Ed. 4 mais je n'ai pas lu le chapitre sur la POO (n'ayant pas le livre sous la main où je me trouve).
    Seulement, n'ayant aucune pratique, je me pose beaucoup de questions sur la POO. Par exemple, je comprends à quoi sert de déclarer une classe abstraite, mais de là à savoir quand l'utiliser en production... c'est une autre affaire.
    Ayant un projet qui me tient à cœur actuellement, je me dis pourquoi pas utiliser de la POO pour m'entraîner. Ce projet est un analyseur ; c'est-à-dire qu'à chaque page actualisée de mon site, l'analyseur va analyser les informations sur l'utilisateur (navigateur avec sa version, provenance du visiteur, etc.). Cependant, je ne sais pas vraiment quelles classes créer pour mettre en place un tel système. Je vous expose ci-dessous ce à quoi j'ai pensé :

    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
     
    class Analyzer extends Visitor {
     
    }
     
    class Visitor {
    	protected $_ua; 
    	protected $_ip; 
     
    	protected function getUA () {
    		return $this->_ua = $_SERVER['HTTP_USER_AGENT'];
    	}
     
    	protected function getIP () {
    		return $this->_ip = $_SERVER['REMOTE_ADDR']; 
    	}
     
    	protected function getIPWithoutProxy () {
    		// not coded yet
    	}
    }
    ?>
    Comme vous le voyez dans ce code très minime, je créé une classe Visitor qui se charge de recueillir les informations du visiteur. Ensuite, j'ai une autre classe, Analyzer, qui hérite de la classe Visitor pour analyser les données du "Visitor".
    Pouvez-vous me donner vos avis sur une telle structure ? Me proposer une meilleur architecture pour mes classes ?

    Merci beaucoup à ceux qui m'aideront.

    P.S. : soyez le plus clair possible dans vos réponses, je débute en POO.

  2. #2
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 502
    Par défaut
    Continue c'est pas mal, pour voir un peu plus loin, regarde des tutos sur la notion de getter et setter !

  3. #3
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Citation Envoyé par Guigui13 Voir le message
    Bonjour à tous,

    Je me suis mis à lire divers tutoriels sur la POO il y a quelques jours. J'ai également le livre PHP 5 Avancé Ed. 4 mais je n'ai pas lu le chapitre sur la POO (n'ayant pas le livre sous la main où je me trouve).
    Seulement, n'ayant aucune pratique, je me pose beaucoup de questions sur la POO. Par exemple, je comprends à quoi sert de déclarer une classe abstraite, mais de là à savoir quand l'utiliser en production... c'est une autre affaire.
    Pour répondre a ta question , les classes abstraites sont assez difficiles a utiliser dans le sens où on peut facilement s'en passer. Ce que je veux dire par la c'est qu'on peut très bien faire des classes sur le même modèle d'un commun accord.
    La où la classe abstraite entre en jeux est que tu vas avoir besoin dans de gros projets de respecter une certaine structure pour disons un ensemble d'entité et la classe abstraite entre en jeux.

    Exemple :

    Imaginons une applications de Gestion d'un Zoo , la plupart des entités sont des animaux , et comme la plupart ils ont des traits commun , imaginons par exemple qu'ils aient tous les méthodes suivantes :

    - Courir
    - Manger
    - "Hurler"
    - Se reposer

    Pour etre sur qu'a la création de mes entités (cheval , girafe , éléphant) je n'oublie pas de leur implémenter les méthodes précédentes , je vais créer une classe abstraite qui servira de patron et qui me donnera la liste des méthodes que je dois implémenter.

    Quand je vais creer mes entités filles , je vais les faire derivée de cette classe abstraite , ainsi , mes classes ne seront pas valides tant qu'elles n'implémenteront pas les méthodes Courir, Manger , Hurler , Se reposer (et évidemment tant que pour chaque entité je n'aurait pas codé ou simplement défini chaque méthode intrinsèque.

    C'est assez abstrait mais une classe abstraite () sert a ça .

    J'espère que tu as compris l'idée.
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 191
    Par défaut
    je suis pas d'accord avec RideKick
    une classe abstraite ne rend pas obligatoire l'implémentation des méthodes c'est seulement quand les méthode sont abstraites et sans code derrière qu'elles le deviennent.

    une classe abstraite sert à verrouiller l'instanciation de cette dernière et surtout à définir des méthodes et des propriétés qu'un ensemble de classe doit hérité.

    si tu veux avoir des méthodes obligatoires héritées de ta classe abstraite tu dois définir les méthodes abstraites et sans implémentation de code.

    si tu n'as que des méthodes sans implémentation de code et aucune propriété tu dois faire une interface.

    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
    abstract class AbstractClass 
    {
        // Force la classe étendue à définir cette méthode
        abstract protected function getValue();
        abstract protected function prefixValue($prefix);
     
        // méthode commune
        public function printOut() {
            print $this->getValue() . "\n";
       }
    }
     
    class ConcreteClass1 extends AbstractClass 
    {
         protected function getValue() {
           return "ConcreteClass1";
         }
     
         public function prefixValue($prefix) {
           return "{$prefix}ConcreteClass1";
        }
    }
     
    class ConcreteClass2 extends AbstractClass 
    {
         public function getValue() {
           return "ConcreteClass2";
         }
     
         public function prefixValue($prefix) {
           return "{$prefix}ConcreteClass2";
        }
    }

  5. #5
    Rédacteur
    Avatar de RideKick
    Homme Profil pro
    Directeur technique
    Inscrit en
    Septembre 2006
    Messages
    5 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5 914
    Par défaut
    Oui en effet tu peux faire les deux .....j'avais zappé ça ce matin !
    Pas de questions techniques en MP please

    Mon site perso

    Mon profil Viadeo

  6. #6
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Citation Envoyé par Helfima Voir le message
    si tu n'as que des méthodes sans implémentation de code et aucune propriété tu dois faire une interface.
    Je reprendrais même cette phrase ainsi :

    si tu n'as que des méthodes sans implémentation de code et aucune propriété tu dois faire une interface.

    Une classe abstraite avec seulement des méthodes abstraites EST une interface.
    Mais le seul fait de la déclarer comme classe t'obligera à l'étendre, ce qui t'empêchera d'étendre une autre classe => architecture bloquée pour rien.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 35
    Par défaut
    Bonsoir à tous,

    Tout d'abord, merci pour vos réponses.
    Pour ce qui est des classes abstraites, j'ai bien lu tous vos messages et la notion s'est éclaircie, merci. Mais en production, je n'y penserai pas...
    J'ai un peu avancé sur ma classe d'analyse.

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    <?php
     
    class Analyzer extends Visitor {
     
    	// vars
    	private $_listOS; 
    	public $os;
     
    	// public functions
    	public function __construct () {
    		$this->_ua = $this->_getUA();
    		$this->_ip = $this->_getIP();
    	}
     
    	// private functions
    	private function detectBrowser($ua) {
    		// not coded yet
    	} 
     
    	private function _detectOS ($ua) {
    		$this->_listOS = Array (
    					'Windows 3.11'			=> 'Win16', 
    					'Windows 95'			=> '(Windows 95)|(Win95)|(Windows_95)', 
    					'Windows 98'			=> '(Windows 98)|(Win98)', 
    					'Windows 2000'			=> '(Windows NT 5.0)|(Windows 2000)', 
    					'Windows XP'			=> '(Windows NT 5.1)|(Windows XP)',
    					'Windows Server 2003'	=> '(Windows NT 5.2)', 
    					'Windows Vista'			=> '(Windows NT 6.0)',
    					'Windows 7'				=> '(Windows NT 7.0)', 
    					'Windows NT 4.0'		=> '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)',
    					'Windows ME'			=> 'Windows ME', 
    					'Sun OS'				=> 'SunOS',
    					'Linux'					=> '(Linux)|(X11)', 
    					'Mac OS'				=> '(Mac_PowerPC)|(Machintosh)', 
    				);
    		foreach ( $this->_listOS as $this->os => $key ) {
    			if ( eregi ( $key, $ua ) ) 
    				break; 
    		}
    		return $this->os; 
    	}
     
    	public function getOS() {
    		$this->os = $this->_detectOS($this->_ua);
    		return $this->os; 
    	}
    	// end of class
    }
     
    class Visitor {
    	protected $_ua; 
    	protected $_ip = array(); 
     
    	protected function _getUA () {
    		$this->_ua = $_SERVER['HTTP_USER_AGENT'];
    		return  $this->_ua; 
    	}
     
    	protected function _getIP () {
    		$this->_ip =  $_SERVER['REMOTE_ADDR'];
    		return $this->_ip; 
    	}
    	// end of class
    }
     
    $Analyzer = new Analyzer(); 
    echo $Analyzer->getOS(); // return 'Windows Vista'
    Un peu plus long que mon premier jet.
    Si vous avez des conseils quant à la structure je préfère privilégier ceci), je suis preneur. Sinon, je continuerai dans cette voie.

    Merci !

  8. #8
    Membre très actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par défaut
    Alors juste par rapport à Analyzer et Visitor tels que proposés par Guigui13:
    Ca ne me paraît pas bon du tout sur un plan conceptuel (parceque sinon, tant qu'il n'y a pas d'erreurs dans php, on peut faire ce qu'on veut)

    Généralement, dans le cadre d'un héritage non multiple, quand une classe B hérite d'une classe A, ça "traduit" le fait que B a un lien direct de concepte par rapport à A. Dans l'exemple précédent du Zoo, on aurait une classe Animal et plusieurs sous classes Cheval, Girafe etc. Un cheval est un animal. Ca a du sens de faire dériver Cheval d'Animal.

    Mais là, un Analyzer n'est pas une variante plus raffinée d'un Visitor. Ce sont deux entitées conceptuelles différentes dans ton programme. Quand d'autres objets manipuleront un Visitor, ça va paraître absurde de leur passer un Analyzer.

    Ce qui me paraîtrait plus judicieux, ce n'est pas de faire dériver Analyzer de Visitor, mais juste de passer un Visitor à un Analyzer qui serait donc une classe à part. Moins de couplage, moins de contraintes, si ce n'est que l'interface de Visitor devra être correctement étudiée pour permettre à un autre objet de l'analyser: quelles méthodes sont plubliques, quelles méthodes sont privées. Ca permet de raisonner sur une encapsulation correcte et efficasse d'un Visitor.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 2 variantes
     
    // passage à la construction (ok car une requête http = un visitor)
    $Analyzer = new Analyzer($visitor); 
    echo $Analyzer->getOS();
     
    // injection via une méthode (encore moins d'agrégation. meilleurs pour des unit tests)
    $Analyzer = new Analyzer; 
    $Analyzer->setVisitor($visitor);
    echo $Analyzer->getOS();
    $Analyzer->setVisitor($visitor2);
    echo $Analyzer->getOS();

Discussions similaires

  1. [WD16] Poo - structures de classe et héritage.
    Par R&B dans le forum WinDev
    Réponses: 10
    Dernier message: 30/05/2011, 09h42
  2. [PHP 5.2] [POO] Structurer une classe
    Par comode dans le forum Langage
    Réponses: 6
    Dernier message: 31/07/2009, 00h50
  3. [POO] Structure de site : PHP et objet, la séparation
    Par Ministar dans le forum Langage
    Réponses: 1
    Dernier message: 23/01/2008, 09h58
  4. [POO] Structure et heritage
    Par juls64 dans le forum C++
    Réponses: 10
    Dernier message: 03/05/2007, 17h56
  5. [POO] Les structures de données comme en C++...
    Par FrankOVD dans le forum Langage
    Réponses: 3
    Dernier message: 27/04/2006, 19h44

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