Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 09-05-2010 16:13:24

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Design Pattern et ZF

Bonjour à tous

ceux qui me connaissent bien savent que j'utilise beaucoup les designs patterns et que je préconise leur usage.

il en est un qui est implémenté directement dans php il s'agit de KVC
Key Value Coding
le principe de KVC est de déclarer les membres d'une classe private ou protected
et d'utiliser tout de même les lectures et affectation directe. ces lectures ou affectations appelants automatiquement les méthodes get et set correspondante.

Code:

class Toto {
  protected $attr;

  pubic function setAttr($value){
     ...
  }

  public function getAttr(){
    ...
  }
}
$obj = new Toto();
$obj->attr = "test";
echo $obj->attr;

cette approche facilite le travail mais devoir écrire tout les accesseurs est un calvaire. php offre pour cela les méthodes __set et __get mais aussi __isset et __unset

voici un exemple simplifié

Code:

  class Object {
    
    public function __set($key, $value){
      $this->$key = $value;
      $this->trace ('set', $key);
    }
    
    public function __get($key){
      if (property_exists($this,$key)){
        $this->trace ('get', $key);
        return $this->$key;
      }
    }
    
    public function trace ($msg, $key){
      echo '<pre>' . $msg . ' ' . $key . ' : ';
      print_r($this);
      echo '</pre>';
    }
    
  }
  
  class myClasse
  extends  Object{
    protected $test;
    
  }

  $obj = new myClasse();
  $obj->test = 45;
  echo $obj->test;

j'ai volontairement ajouté la méthode trace pour qu'on puisse voir le fonctionnement.
on vois rapidement que si on implémente ces méthodes dans une classe de base on en bénéficie partout. bien sur ce n'est qu'un exemple et il faudrait les améliorer en levant une exception lorsque on tente de lire une clef inexistante.
une classe fille peut redéfinir une méthode pour la spécialiser par exemple.

on peut ainsi définir des classes qui acceptent qu'on ajoute dynamiquement des membres et d'autres non.

bref ZF utilise en partie cette façon de faire. et il peut être très pratique de suivre l'exemple.

mais le design patern KVC vas beaucoup plus loin
et je pense qu'une implémentation au coeur de ZF le rendrait beaucoup plus souple.

la théorie définie une approche pour les membres qui sont des collections. mais là ni php ni ZF la suivent.
pourtant il est possible de l'implémenter.

la problématique concerne donc des membres représentants des liste d'éléments. KVC préconise de définir une convention d'accès aux éléments de ces collection.
par exemples prenons un album celui-ci à des membres comme le titre, la pochette, le compositeur, l'interprète etc. mais aussi la liste des pistes
KCV propose de définir une convention comme counOfPistes pour conter les pistes, getItemOfPistesAtIndex getItemOfPistesForKey addItemOfPiste removeItemFromPistes etc.
la construction consiste donc  définir des mots clefs qui associés au nom du membre va définir un accesseur.

là encore si on l'implémente dans une classe de base on en bénéficie partout.

là encore je vous donne une implémentation basique pour illustrer le principe. il conviendrait de vérifier le type du membre gérer des exceptions et les méthodes d'accès propre à certaines classes. (itérateurs par exemple)
KVC prévoit de plus si les type des éléments le permettent l'ajout d'acccesseurs comme sumOf avgOf etc.

encore un fois php nous permets l'implémentation cette fois avec __call
on va prendre la méthode vérifier qu'elle corresponds à un des accesseurs de notre convention et si c'est le cas récupérer la clef du membre et invoquer la méthode adéquate.
le tout pouvant évidement être surcharger par une classe héritière soit de façon globale en redéfinissant __call soit en redéfinissant une des méthodes.

Code:

<?php
  class Object {
    
    public function __set($key, $value){
      $this->$key = $value;
      $this->trace ('set', $key);
    }
    
    public function __get($key){
      if (property_exists($this,$key)){
        $this->trace ('get', $key);
        return $this->$key;
      }
    }
    
    
    public function __call($method, $arguments){    
      if (preg_match('/getItemOf([A-Z][a-z]+)AtIndex/', $method, $matches)){
        $this->trace($method, $arguments[0]);
        return $this->getItemOfAtIndex(strtolower($matches[1]),$arguments[0]);
      }
      
      if (preg_match('/countOf([A-Z][a-z]+)/', $method, $matches)){
        $this->trace($method, null);
        return $this->contOf(strtolower($matches[1]));
      }
    }
    
    
    protected function getItemOfAtIndex($key, $index) {
      $collection = $this->__get($key);
      return $collection[$index];
    }
    
    protected function contOf($key) {
      $collection = $this->__get($key);
      return count($collection);
    }
    
    public function trace ($msg, $key){
      echo '<pre>' . $msg . ' ' . $key . ' : ';
      print_r($this);
      echo '</pre>';
    }
    
  }
  
  class myCollection
  extends  Object{
    protected $elements;
    
    public function __construct(){
      $this->elements = array(5, 6, 7, 8);
    }
  }

  $liste = new myCollection();
  echo $liste->countOfElements();
  echo $liste->getItemOfElementsAtIndex(2);

cette façon de faire apporte beaucoup de souplesse mais dans un outil comme ZF il serait intéressant que cela soit intégré dans le FramWork

la convention et les méthodes correspondantes étants dans le FramWork on aurait beaucoup moins de code à écrire

Code:

  class myCollection
  extends  Object{
    protected $elements;
    
    public function __construct(){
      $this->elements = array(5, 6, 7, 8);
    }
  }

  $liste = new myCollection();
  echo $liste->countOfElements();
  echo $liste->getItemOfElementsAtIndex(2);

Voilà un petit tour dans le monde KVC.

j'ouvre le débat
Pensez-vus qu'il faille proposer l'intégration complète de KVC dans ZF (3.0) ?
A+JYT

Hors ligne

 

#2 09-05-2010 18:03:42

Intiilapa
Membre
Date d'inscription: 03-02-2009
Messages: 95

Re: Design Pattern et ZF

Je me suis déjà posé cette problématique avec une classe qui irait plus loin que stdClass (je dirai même qu'on pourrait avoir ce principe de classe abstraite pour gérer un pattern et éviter les corvées de lignes de code y compris pour la gestion des modèles, des dépendances, des interactions, etc). Apparemment, ce n'est pas le choix pour le Zend Framework, puisque le fait de factoriser dans une classe Options la méthode setOptions(), exprimé pour uniformiser les constructeurs dans ZF 2.0, n'aura pas lieu.

J'aurai tendance à dire que certaines classes ZF bloquent volontairement l'accès à certains attributs. Cela reste toujours possible en ajoutant un tableau de noms d'attributs exclus des méthodes magiques.

Est-ce que le fait de prendre la place unique de classe parente est un frein dans de gros projets ?

C'est attrayant, mais cela semble plus être le saint graal des débutants que des experts ... quelles en sont les raisons ?

Hors ligne

 

#3 09-05-2010 18:10:43

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: Design Pattern et ZF

J'utilise de temps en temps les fonctions magiques (__get, __set,...), mais de façon général, j'évite d'en mettre partout parce que ça rend le code pas mal illisible. Les outils de dev ne permettent pas de suivre les classes,...

Bref, perso je ne suis pas pour généraliser les magic functions partout dans le code, plus pour des raisons pratiques que pour des raisons théoriques...

A+, Philippe


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#4 09-05-2010 21:58:06

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: Design Pattern et ZF

Salut,

L'idée est intéressante et j'ai souvent été tenté d'implémenter des concepts à base de méthodes magiques. Et je l'ai fait d'ailleurs, mais au final je ne les utilise pas ou presque pas et préfère passer par de bons vieux getters, pour travailler en équipe c'est bien plus conventionnel et l'auto-complétion est assurée.

Comme philippe j'évite le plus possible d'utiliser les functions magiques de PHP, bien qu'elles permettent effectivement d'apporter beaucoup de "magie" bien pratique, je suis plutôt partisan du "les fonctions magiques c'est le mal et c'est une plaie ouverte de PHP".

Doctrine (1.2) n'utilise par exemple que ça et c'est assez contraignant, tous les IDE ne gèrent pas bien les doc blocks pour les membres. Au final je me retrouve avec des dév. qui ne connaissent pas bien certaines classes et qui ne vont pas fouiller dedans pour voir ce qu'il est possible de faire et qui re-codent certaines choses de leur côté.

C'est bien dommage, le pattern dans son ensemble est très intéressant mais je préfère un contrat et me palucher l'implémentation.


A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#5 10-05-2010 08:40:40

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: Design Pattern et ZF

je ne pense pas que ce soit pour le code que l'on écrit que cela est intéressant

nombres d'interfaces définie dans ZF demande l'implémentation de telle ou telle méthode
et au final on a des noms très différents alors que leur approche sémantique est la même.

l'avantage de KVC est alors de rendre tout cela uniforme et de simplifier l'écriture de méthodes génériques.

mon propos n'est pas de généraliser l'usage des fonctions "magiques" mais bien le design pattern
mon exemple montrait juste qu'on peut facilement l'implémenter en php à l'aide des fonctions "magiques"

A+JYT

Hors ligne

 

#6 10-05-2010 12:12:40

armetiz
Membre
Lieu: Lyon
Date d'inscription: 26-02-2010
Messages: 53
Site web

Re: Design Pattern et ZF

Cela serai disponible pour ZF2. Du moins pour la partie Model du MVC.
Sachant que DC 1.2 utilise le KVC, je suppose que DC 2 le fera aussi..

C'est pratique et chiant à la fois comme le dit Delprog, déjà que les IDE PHP ne sont pas géniaux dû au typage faible de PHP, cela rajoute une couche de "flou".

Toujours est-il que si je devais choisir avec ou sans KVC, je prendrai avec.

Hors ligne

 

#7 10-05-2010 12:18:47

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: Design Pattern et ZF

Je suis tout à fait d'accord pour une uniformisation des interfaces de Zend. Mais dans ce cas j'imagine plutôt une factorisation dans une nouvelle interface, tout comme Iterator, qui contractualise le pattern KVC mais qui ne propose pas d'implémentation magique.

Je pense qu'il serait trop contraignant de devoir étendre une classe abstraite par ex.

A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#8 10-05-2010 13:02:38

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: Design Pattern et ZF

Comme tout le monde , j'évite les magics.
D'ailleurs, Doctrine 2 n'a t-il pas tendance justement à supprimer l'utilisation de magics ?


----
Gruiiik !

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages