OVH Cloud OVH Cloud

configurer un objet

12 réponses
Avatar
Raphael Wils
Bonjour-Bonsoir

J'aimerai savoir quelle est le meilleur procédé, c'est à dire fiable et
évolutif, pour configurer un objet avec un certain nombre de parametres,
sachant que ces parametres doivent être validés et modifiés, utilisés
pour configurer d'autres propriétés privées et stockés durant
l'utilisation du script et que la valeur validée et modifiée de certain
d'entre eux doit pouvoir être lue :

1. en lui envoyant un tableau

$parametres = array (
'truc' => 54,
'machin' => false,
'chose' => 'my name is Raphael'
);
superbeObjet->set($parametres);

2. en utilisant une méthode set pour chaque parametre :

superbeObjet->setTruc(54);
superbeObjet->setMachin(false);
superbeObjet->setChose('my name is Raphael');

3. en utilisant une méthode set unique avec le nom et la valeur du
parametre :

superbeObjet->set('truc', 54);
superbeObjet->set('machin', false);
superbeObjet->set('chose', 'my name is Raphael');

--
Raphaël
http://www.r-wils.com
« Don't mean a thing if you ain't got that swing ! »

10 réponses

1 2
Avatar
Clifden

1. en lui envoyant un tableau

$parametres = array (
'truc' => 54,
'machin' => false,
'chose' => 'my name is Raphael'
);
superbeObjet->set($parametres);

2. en utilisant une méthode set pour chaque parametre :

superbeObjet->setTruc(54);
superbeObjet->setMachin(false);
superbeObjet->setChose('my name is Raphael');

3. en utilisant une méthode set unique avec le nom et la valeur du
parametre :

superbeObjet->set('truc', 54);
superbeObjet->set('machin', false);
superbeObjet->set('chose', 'my name is Raphael');



*Si* tu es en php5:
La 3ème et la 2ème solution revienne au meme si tu utilise la magic
function __set

class objet {
private $_truc;
private $_machin;
private $_chose;
(...)
public function __set($name,$value) {
if ($name=='truc') $this->_truc=$value;
if ($name=='machin') $this->_machin=$value;
if ($name=='chose') $this->_chose=$value;
}
(...)
}

Ensuite, rien ne t'empeche d'avoir pour chaque propriété, une fonction
privée qui permet de la "setter". Dans chacune de ces fonction, tu fais
les vérifs necessaires. Ne te reste plus qu'ensuite dans la fonction
__set à faire les appels necessaires.

Après, tu peux aussi utiliser la méthode 1 et la 2. Avantages:
construire l'objet avec un seul parametre (qui peux du coup être un
tableau provenant d'une requete SQL), et avoir à disposition (methode 2)
des fonction permettant de setter à loisir telle ou telle propriétés au
cours du script.

Voilà mes avis sur la question

Avatar
Marc
Bonjour-Bonsoir

J'aimerai savoir quelle est le meilleur procédé, c'est à dire fiable et
évolutif, pour configurer un objet avec un certain nombre de parametres,
sachant que ces parametres doivent être validés et modifiés, utilisés
pour configurer d'autres propriétés privées et stockés durant
l'utilisation du script et que la valeur validée et modifiée de certain
d'entre eux doit pouvoir être lue :



une autre methode, c'est de contruire des classes de base simple
sans methodes elaborées pour le parametrage, mais de laisser
ce travail aux classes filles.


class Core {

var $name; # nom de la classe.

function Core(){
$this->name = null;
}
}


class Person extends Core{

function Person(){
$this->Core();
$this->name = 'foobar';
}
}

class Major extends Person{
function Major(){
$this->Person();
$this->name = 'director';
}
}

Avatar
loufoque
Clifden a dit le 15/10/2005 01:02:

class objet {
private $_truc;
private $_machin;
private $_chose;
(...)
public function __set($name,$value) {
if ($name=='truc') $this->_truc=$value;
if ($name=='machin') $this->_machin=$value;
if ($name=='chose') $this->_chose=$value;
}
(...)
}


C'est quoi l'intérêt par rapport à
class objet {
public $truc;
public $machin;
public $chose;
(...)
}

Avatar
Clifden

class objet {
private $_truc;
private $_machin;
private $_chose;
(...)
public function __set($name,$value) {
if ($name=='truc') $this->_truc=$value;
if ($name=='machin') $this->_machin=$value;
if ($name=='chose') $this->_chose=$value;
}
(...)
}



C'est quoi l'intérêt par rapport à
class objet {
public $truc;
public $machin;
public $chose;
(...)
}


C'est l'interet de pouvoir faire de l'encapsulation (et donc du controle
des données), tout en pouvant continuer à acceder aux propriétés par une
syntaxe simple.

J'ai par exemple fait une classe user (qui represente l'internaute sur
le site (loggué ou pas loggué). Si je veux modifier ses propriétés, par
exemple sa langue d'affichage, j'écris: $user->langue='es';
en fait c'est la fonction __set qui est appelée, qui appelle elle meme
une fonction privée _set_langue($new_langue). Dedans, je verifie si la
nouvelle valeur est bien différente de l'ancienne, si elle est valable
(appartement à une liste de langue possible), et je met alors un flag à
true pour indiquer que la propriété langue a changé. Ainsi dans le
destructeur, je peux mettre à jour les infos du user en bd aussi
finement que possible par une requete update sur les champs ayant été
modifié.

Coté code de la page, je me rends pas compte de tout çà...


Avatar
bruno modulix
Clifden wrote:
(snip)

C'est l'interet de pouvoir faire de l'encapsulation (et donc du controle
des données),


s/encapsulation/masquage d'information/

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
clifden
C'est l'interet de pouvoir faire de l'encapsulation (et donc du controle
des données),



s/encapsulation/masquage d'information/



Excuse moi, mais je n'ai pas compris ta réponse.


Avatar
bruno modulix
clifden wrote:
C'est l'interet de pouvoir faire de l'encapsulation (et donc du controle
des données),




s/encapsulation/masquage d'information/



Excuse moi, mais je n'ai pas compris ta réponse.


<pedant>
Ce que tu décris comme de l'encapsulation est du masquage d'information.
Le concept d'encapsulation se réfère essentiellement au fait de
'packager' ensemble les données et les traitements opérant sur ces
données. Le masquage d'information consiste à rendre inaccessibles ou
difficilement accessibles[1] les détails d'implémentation, de sorte à ce
que seule l'API prévue soit utilisée.

[1] et encore... en Python et en PHP4, c'est juste une convention
consistant à préfixer les identifiants par un _underscore.
</pedant>

Mais bon, la distinction relève un peu du mauvais traitements aux
animaux, voire de l'enculage de mouche. Je confesse...

Accessoirement, s/untruc/unautre/ est un script sed qui remplace toute
occurrence de untruc par un autre.

Est-ce plus complet ?-)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"



Avatar
clifden


<pedant>
Ce que tu décris comme de l'encapsulation est du masquage d'information.
Le concept d'encapsulation se réfère essentiellement au fait de
'packager' ensemble les données et les traitements opérant sur ces
données. Le masquage d'information consiste à rendre inaccessibles ou
difficilement accessibles[1] les détails d'implémentation, de sorte à ce
que seule l'API prévue soit utilisée.

[1] et encore... en Python et en PHP4, c'est juste une convention
consistant à préfixer les identifiants par un _underscore.
</pedant>


C'est exactement ce que les magic function __get et __set permettent de
faire. C'est que je me suis mal exprimé:

En faisant: (cas d'école sans interet)

class chaine_caractere {
private $_chars;
private $_length;

function __set($name,$value) {
if ($name=='chars') {
$this->_chars=$value;
$this->_length=strlen($value);
}
if ($name=='length') { }
}
}

Je :
* Masque les données interneq
* Effectue un traitement spécial afin d'empecher une desynchronisation
entre $_chars et $_length

Coté code client, l'utilisateur ne sais pas ce qui se passe en interne,
et on a donc l'encapsulation.

Avatar
bruno modulix
clifden wrote:


<pedant>
Ce que tu décris comme de l'encapsulation est du masquage d'information.
Le concept d'encapsulation se réfère essentiellement au fait de
'packager' ensemble les données et les traitements opérant sur ces
données. Le masquage d'information consiste à rendre inaccessibles ou
difficilement accessibles[1] les détails d'implémentation, de sorte à ce
que seule l'API prévue soit utilisée.



C'est exactement ce que les magic function __get et __set permettent de
faire. C'est que je me suis mal exprimé:

En faisant: (cas d'école sans interet)

class chaine_caractere {
private $_chars;
private $_length;

function __set($name,$value) {
if ($name=='chars') {
$this->_chars=$value;
$this->_length=strlen($value);
}
if ($name=='length') { }


Ceci devrait lever une exception signalant que l'attribut est en lecture
seule.

}
}

Je :
* Masque les données interne
* Effectue un traitement spécial afin d'empecher une desynchronisation
entre $_chars et $_length

Coté code client, l'utilisateur ne sais pas ce qui se passe en interne,
et on a donc l'encapsulation.


Oui, mais le masquage d'information n'est pas nécessaire pour ça. C'est
l'encapsulation qui compte.

Je te le refais en Python

class ChaineCaracteres(object):
def __init__(self, chars):
self.chars = chars

def _set_chars(self, chars):
self._chars = chars
self._len = len(chars)

chars = property(fget=lambda self: self._chars, fset=_set_chars)
len = property(fget=lambda self: return self._len)

Ni _chars, ni _len (ni même _set_chars) ne sont masqués. Il y a pourtant
encapsulation. Tu me diras que l'utilisateur de la classe peut tout
casser en accédant directement à _char ou _len. C'est vrai. Mais c'est
son problème.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
clifden

Ni _chars, ni _len (ni même _set_chars) ne sont masqués. Il y a pourtant
encapsulation. Tu me diras que l'utilisateur de la classe peut tout
casser en accédant directement à _char ou _len. C'est vrai. Mais c'est
son problème.



Là je ne suis pas d'accord avec toi.
Je pense que c'est le problème de la classe de faire en sorte de rester
intègre. En C++, avec l'utilisation de pointeurs, c'est le segmentation
fault assuré, et donc une classe qui fait tout planter à tout bout de
champs car n'effectuant pas les verifs necessaires, elle propage ses
propres problèmes d'intégrité.
Et dans le cas de classes derivées? si la classe de base ne gère pas
correctement ses variables qui sont private, quand est-il pour les
classes dérivées: le bordel.

De plus, et pour en revenir à du PHP, si la modif d'une variable de
classe necessite un update en BD par exemple, une mauvaise utilisation
(qui ne fait d'erreur) de la classe peux aussi mettre en l'air la BD.

C'est pour çà que j'aime bien __get et __set car ils permettent
d'utiliser la classe comme si de rien n'était tout en pouvant mettre du
code derrière pour agir en conséquence. Et cela evite d'avoir une
ribembelle de get_truc(),get_machin(), set_truc($truc), set_machin($machin).

1 2