POO théorie/pratique getter setter accès aux propriétés

hannibalguy Messages postés 3 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 16 mai 2012 - 13 mai 2012 à 13:08
hannibalguy Messages postés 3 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 16 mai 2012 - 16 mai 2012 à 01:32
Bonjour.

Je me posait la question suivante :
Théoriquement (sur la POO en générale) et pratiquement (php donc) quelle est la meilleur pratique, s'il y en a une, pour accèder (lire/écrire) aux propriétés d'un objet issu ou non d'un résultat de bdd.
Par exemple dans cet extrait d'une classe abstraite:
protected $_data; // vide si nouvel objet ou résultat BDD
public function __call($name, $arguments) {
    if ( substr($name, 0, 4) == 'get_' ) {
        $property = substr($name, 4);
        if ( isset($this->_data->$property) ) 
            return $this->_data->$property;
        else throw new Exception("$property not found.");
    }
    // et puis pareil avec 'set_', 'add_' etc...
}

// ou plutôt ça : 
public function __get($key) {
    if ( isset($this->_data->$property) ) 
            return $this->_data->$property;
        else throw new Exception("$property not found.");
} // et puis __set($key, $value)... etc

// ou encore putôt ça : 
public function setValue($key, $value) {

} // et getValue($key), etc...

SACHANT QUE : cet objet peut enregistrer ses propriétés dans une bdd, ET que l'opération d'enregistrement vérifie que chaque $_data->$property est dans un "dictionnaire de donnée" et conforme (type, taille...).

Y a-t-il "LA" bonne manière ? L'une d'entre elles est-elles moins "sécure" ou la porte ouverte à des comportements inattendus dans ce cadre là ?

J'espère qu'il y en à une, sinon je n'arriverais pas à me décider

Bonne journée.

4 réponses

TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
14 mai 2012 à 02:22
Salut,

Une bonne pratique est déjà de respecter l'encapsulation. À cause de tes __call, __get et __set tu explose ça. Ces méthodes magiques sont très utiles... mais dans des cas précis et pas forcément si courants que ça.

Soit dit en passant, je ne vois pas ce que viens faire la base de données là dedans. Avec un bon design cette dernière est totalement découplée de tes objets "métier".
0
hannibalguy Messages postés 3 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 16 mai 2012
14 mai 2012 à 14:13
Bonjour TychoBrahe.

l' encapsulation... En effet je ne maîtrise pas trop (du tout ?) les concepts.
Donc je note : ne pas utiliser les méthodes magiques n'importe comment.

Pour les objets "métier", je vois un peu ce que c'est (de loin).

J'ai conçu tant bien que mal un truc comme ça :
- Pour la base de donnée, une classe multiton "mdbc" pour me connecter via PDO sur du mysql, ou du sqlite, (ou autre plus tard).
- Une classe "dbschema" pour concevoir -via l'instance multiton- un "dictionnaire de donnée" de l'objet.
- Une class abstraite "dbObjet" qui __construct() une instance "mdbc" et "dbshema", diposent de méthode save, update, load, delete, checkData, etc... et les __get(), __set() (pour l'instant utilisés pour accès aux propriété)
- Une class "dbCollection" pour faire des collections d'objets "dbobjet" et qui implemente une classe "dbSql" pour construire des requetes plus complexe.
- Et enfin des objets "user", "document", etc, qui dérivent de "dbObjet"
Ce sont ces dernier qui construise (ou chargent) l'instance multiton "mdbc", éventuellement le "dictionnaire" via "dbschema" ou via un xml ou un ini (bref on choisit) et surchargent (c'est le terme ?) si besoin save, update, delete, load, __construct() etc...

Il me semblait (tout content de moi-même ) que j'avais bien découpé mon bazar.
Bon, n'étant pas développeur, je vais peut-être d'abord coder ça plus propre et plus respectueusement des règles avant de me lancer dans du plus complexe.
0
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
15 mai 2012 à 18:24
Salut,

Je ne sais aps comment tu as fait ton truc, mais si tu dois faire la différence entre un objet créé à partir de la DB et un objet créé autrement, il y a un problème. Concernant l'accès aux données, c'est encore un problème récurent que de savoir comment bien le faire, chaque "technique" à des avantages et des défauts. Tu devrais regarder du coté des DAO et même sans doute les pattern builder, factory method, abstract factory etc, il y a plein de choses intéressantes à voir.

Pour ce qui est des méthodes magiques __get, __set et __call, ce que je leur reproche c'est qu'il est tentant de les utiliser afin de donner accès à toutes les propriétés comme si elles étaient publiques. Abuser de ça reviens à totalement ignorer les différences de visibilités (public, protected et private) et donc passer à côté de fonctionnalités importantes qui sont là avant tout pour t'aider et te protéger contre toi même. Bien entendu elles ont leur utilité, par exemple je conçoit parfaitement que __get soit utilisé dans le cadre de la création d'une bibliothèque de gestions d'arbres n-aires afin de donner accès aux enfants (mais pas à toutes les propriétés) de manière simple.
0
hannibalguy Messages postés 3 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 16 mai 2012
16 mai 2012 à 01:32
Hello.

En fait, il y a une classe abstraite "dbObject" qui fournis une connexion PDO, des methodes de check (valeurs de champs, de structure de table , etc), de sauvegarde, de del, d'update etc.... Les classes filles passent des paramètres de construction (instance de connexion, source de dictionnaire de donnée, identification de clé, etc) tout ça avec des implements, des abstracts, des multitons et autres.
Les patterns builder et autres abstract factory : j'en suis pas encore là . J'ai encore du mal à bien saisir comment ça fonctionne. (bon comme je disais, je ne suis pas développeur). J'avais lu (et relu) les tutos et sources de Malalam, Neige etc sur ces patterns : ben j'ai rien compris.
Faudra que je repotasse ça.

J'essai autant que possible de mettre du private et du protected. Mais PDO qui me retournait des objets de classe "X" remplissait en propriétés publiques (je viens tout juste de découvrir dans la doc qu'un paramètre pouvait forcer l'initialisation de la classe avant de la peupler ). Maintenant j'ai modifier le __get() et __set() pour ne renvoyer que les propriétés de l'objet issu du résultat PDO (dans une propriété array private) ET passage dans une moulinette pour vérifier que c'est dans les clous avant de sortir ou d'entrer. Bon bien sur, je perd la possibilité d'utiliser ces magics pour les évolutions futures. Mais bon pour l'instant je n'en ai pas d'autre utilité.

La route est longue...
0
Rejoignez-nous