Design pattern pour la construction de mes pages

Signaler
Messages postés
9
Date d'inscription
vendredi 12 août 2005
Statut
Membre
Dernière intervention
22 juillet 2010
-
Messages postés
9
Date d'inscription
vendredi 12 août 2005
Statut
Membre
Dernière intervention
22 juillet 2010
-
Salut à tous,

Voila, j'ai bien regardé les tutos de Malalam sur les design pattern, plus particulièrement l'exemple de la fabrication du sandwich :).

Je suis en train de développer un "portail" qui posséde plusieurs rubriques (ex: mode, maman, minceur, beaute, psycho). Les home de ses rubriques ont toutes un point commun, elles auront par exemple, le dernier article publié, la dernière recette, le dernier quizz, le dernier sondage etc.... Donc je me disais que je pourrais faire un "Builder" pour construire mes rubriques.

Cela me ferait un processus dans ce genre :

class rubrique {

    /**
     * Ses propriétés
     *
     * @var string
     */
  

    private $db;
   
    private $sRubrique;
   
    private $sActuce;
   
    private $sBoutique;
   
    private $sSondage;

    /**
     * Setter pour la rubrique
     */

    public function setRubrique ($sRubrique) {

           $this ->sRubrique = $sRubrique;
    }

    /**
     * Setter pour les astuces
     *
     * @param string $sActuces
     */

    public function setAstuce () {
       
        //test
        $this ->sActuce = 'derniere astuce';

    }
   

    /**
     * Setter pour la boutique
     *
     * @param string $sBoutique
     */

    public function setBoutique () {
       
        //test
        $this ->sBoutique = 'dernier produit';

    }
       

    /**
     * Setter pour le sondage
     *
     * @param string $sSondages
     */

    public function setSondage() {

        //test
        $this ->sSondage = 'dernier sondage';

    }
   

    /**
     * Test de la construction de la rubrique
     *
     * @return string
     */

    public function __toString() {

        $sReturn = 'Votre rubrique '.$this -> sRubrique.' est compose du : '.$this ->sActuce.' , '.$this ->sBoutique.' , '.$this ->sSondage;

        return $sReturn;

    }

   

}

abstract class rubriqueBuilder {

    /**
     * La rubrique qu'il va créer
     *
     * @var rubrique
     */

    protected $oRubrique;   

    /**
     * Getter pour récupérer la rubrique créé
     *
     * @return rubrique
     */

    public function getRubrique () {

        return $this ->oRubrique;

    }   

    /**
     * Initialisation de la création de la rubrique
     *
     */

    public function createNewRubrique() {

        $this ->oRubrique = new rubrique;
       
    }

    /**
     * Séquence de construction
     *
     */

    abstract public function addAstuce();

    abstract public function addBoutique();

    abstract public function addSondage();

}

class uneRubrique extends rubriqueBuilder {

    public function initRubrique($sRubrique) {
       
        $this ->oRubrique ->setRubrique($sRubrique);
   
    }

    public function addAstuce() {

        $this ->oRubrique ->setAstuce();

    }

    public function addBoutique() {

        $this ->oRubrique ->setBoutique();

    }   

    public function addSondage() {

        $this ->oRubrique ->setSondage();

    }

}

class factory {

    /**
     * Le MONTEUR CONCRET dont il va se servir
     *
     * @var rubriqueBuilder
     */

    private $oRubriqueBuilder;

   

    /**
     * Setter qui va initialiser le MONTEUR CONCRET désiré
     *
     * @param rubriqueBuilder $rubriqueBuilder
     */

    public function setRubriqueBuilder (rubriqueBuilder $rubriqueBuilder) {

        $this ->oRubriqueBuilder = new $rubriqueBuilder;

    }

   

    /**
     * Getter, retournant la rubrique créé par répercussion
     *
     * @return rubrique
     */

    public function getRubrique () {

        if (is_null ($this ->oRubriqueBuilder)) {

            throw new Exception (__METHOD__.'() : aucun rubriquebuilder défini');

        }

        return $this ->oRubriqueBuilder ->getRubrique();

    }

   

    /**
     * La séquence de construction de la rubrique
     *
     */

    public function createRubrique($sRubrique) {

        if (is_null ($this ->oRubriqueBuilder)) {

            throw new Exception (__METHOD__.'() : aucun rubriquebuilder défini');

        }

        $this ->oRubriqueBuilder ->createNewRubrique();
       
        $this ->oRubriqueBuilder ->initRubrique($sRubrique);

        $this ->oRubriqueBuilder ->addAstuce();

        $this ->oRubriqueBuilder ->addBoutique();

        $this ->oRubriqueBuilder ->addSondage();

    }

}

try {

    $oRubrique = new uneRubrique;

    $oFactory = new factory;

    $oFactory ->setRubriqueBuilder ($oRubrique);
   
    $oFactory ->createRubrique('maman');

    echo $oFactory ->getRubrique();

    echo '
';
   
    $oFactory ->createRubrique('sante');
   
    echo $oFactory ->getRubrique();

    echo '
';      
 

} catch (Exception $e) {

    echo $e;

}

J'aurais besoin de savoir si je fais fausse route ou pas ?

Sachant que dans certaine rubriques par exemple le module boutique ne sera pas intégré donc dans ce cas là il ne faudrait pas que le Monteur Concret fasse un "addBoutique". Faudrait-il donc que je fasse un Monteur par rubrique ? ça risque de faire lourd ?

J'aimerais aussi instencier ma class SQL et aussi instancier mon moteur Smarty. Dois - je instancier ces classes en faisant par exemple dans le Monteur Concret:

       $this ->oRubriqueBuilder ->connectSql();
       
       $this ->oRubriqueBuilder ->initSmarty();

Bref j'essaie de me mettre à la POO pour ce développement mais je ne sais pas si m'y prend de la bonne manière ?

3 réponses

Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
Hello,

déjà, ravi que mes tutos t'aient servi :-)

Pour ce qui est de ton code : c'est pas mal, mais il a un inconvénient. Tu ne peux pas, de cette manière, implémenter correctement la récupération de la dernière  astuce de la rubrique "maman", par exemple, vu le parti pris de créer une classe uneRubrique.
Le principe du builder est différent : tu devrais avoir une classe concrète par type de rubrique, étandant simplement une classe abstraite "rubrique".  Ainsi, dans ces classes concrètes, tu pourras par exemple implémenter le nom du champ clef de ta table rubrique à attaquer, par exemple.
Avec ton code tel quel, tu vas avoir beaucoup de mal à implémenter les spécificités de chaque rubrique.
La structure du code deviendrait alors :
class rubrique
abstract class rubriqueBuilder
class factory
class mamanRubrique extends rubriqueBuilder
class santeRubrique extends rubriqueBuilder

et ce, si on se colle au design pattern.
Mais bon...mon tuto expliquait juste le fonctionnement des design pattern tels qu'imaginés. On peut les adapter au cas par cas :-)
Ceci dit, dans ton cas, je pense que coller au builder fonctionne très bien.
Messages postés
9
Date d'inscription
vendredi 12 août 2005
Statut
Membre
Dernière intervention
22 juillet 2010

Merci de ta réponse rapide :-) !

Effectivement avec le code tel quel, je ne pourrais pas implémenter les spécifités de chaque rubrique. A moins de faire un petit changement dans la classe factory.

class factory {

    /**
     * Le MONTEUR CONCRET dont il va se servir
     *
     * @var rubriqueBuilder
     */

    private $oRubriqueBuilder;
   

    /**
     * Setter qui va initialiser le MONTEUR CONCRET désiré
     *
     * @param rubriqueBuilder $rubriqueBuilder
     */

    public function setRubriqueBuilder (rubriqueBuilder $rubriqueBuilder) {

        $this ->oRubriqueBuilder = new $rubriqueBuilder;

    }  

    /**
     * Getter, retournant la rubrique créé par répercussion
     *
     * @return rubrique
     */

    public function getRubrique () {

        if (is_null ($this ->oRubriqueBuilder)) {

            throw new Exception (__METHOD__.'() : aucun rubriquebuilder dŽfini');

        }

        return $this ->oRubriqueBuilder ->getRubrique();

    }
   

    /**
     * La séquence de construction de la rubrique
     *
     */

    public function createRubrique($sRubrique, $aElements) {

        if (is_null ($this ->oRubriqueBuilder)) {

            throw new Exception (__METHOD__.'() : aucun rubriquebuilder dŽfini');

        }      

       
        $this ->oRubriqueBuilder ->createNewRubrique();
       
        $this ->oRubriqueBuilder ->connectSql();
       
        $this ->oRubriqueBuilder ->initSmarty();  
       
        $this ->oRubriqueBuilder ->initRewriteUrl();          
       
        $this ->oRubriqueBuilder ->initRubrique($sRubrique);
 
        // appel des methodes que l'on souhaite
        foreach($aElements as $element) {
       
            $this ->oRubriqueBuilder ->$element();
       
       
        }
       
    }

}

//Test

try {

    $oRubrique = new uneRubrique;

    $oFactory = new factory;

    $oFactory ->setRubriqueBuilder ($oRubrique);
   
    $oFactory ->createRubrique('maman', array('addAstuce', 'addBoutique', 'addSondage'));
   
    echo $oFactory ->getRubrique();

    echo '
';
   
    $oFactory ->createRubrique('sante', array('addAstuce', 'addBoutique'));
   
    echo $oFactory ->getRubrique();

    echo '
';

    
 

} catch (Exception $e) {

    echo $e;

}

Bon après ce n'est peut-être pas une méthode très catholique.

Qu'en penses-tu ?
Messages postés
9
Date d'inscription
vendredi 12 août 2005
Statut
Membre
Dernière intervention
22 juillet 2010

Encore moi,

En regardant d'autre design pattern, je me disais que peut-être le Pattern Stratégie pourrait mieux correspondre à mon dev.
C'est à dire mes rubriques ont dans certains cas des sous-rubriques en plus ou en moins donc il y a une notion de "contexte". Dans le contexte "Maman", j'aurais besoin par exemple d'implémenter la méthode "setRecette" alors que dans le contexte "Mode" je n'ai pas besoin de l'implémenter.

Est-ce que je me trompe ?