Méthode d'objet via une interface fluide.

ViPHP
ViPHP | 4674 Messages

16 juin 2007, 20:52

Bonjour :)

Je viens de découvrir les interfaces fluides.
C'est par exemple utilisé sur ZendFramework : Chapitre 20. Zend_Mail

Voici l'exemple qu'ils utilisent :
$mail->setBodyText('Ceci est le message.')
    ->setFrom('[email protected]', 'un expéditeur')
    ->addTo('[email protected]', 'un destinataire')
    ->setSubject('sujet de test')
    ->send();
L'objectif d'« une interface dite fluide c'est que chaque méthode retourne la référence à l'objet appelé ».
J'aime bien cette idée, mais je me pose une question : c'est sûrement lourd à gérer pour PHP non ? Retourner un booléen ou un objet, c'est pas tout à fait pareil.

Je voulais donc savoir si on aurait pas tendance à laisser cette idée de côté pour favoriser la vitesse de PHP ou non. Parce que, c'est quand même pratique à écrire, mais je doute de l'économie de ressources de cette méthode.

Merci pour vos réponses et bon appétit à tous ;)
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

16 juin 2007, 21:01

Aucune lourdeur, puisqu'en PHP5 ce n'est qu'une référence (un pointeur si tu as fait du C ou du Pascal) qui est retourné et pas tout l'objet. Pour avoir le même comportement en PHP4 il faut déclarer la fonction comme retournant une référence grâce à "&" :
function & maFonction() {
  return $this;
}
Si on met de côté cette syntaxe c'est surtout pour des raisons de conception du code. D'une part cela ne peut concerner que des setters et l'intérêt est donc limité. D'autre part en cas d'échec d'un setter il y a deux possibilités :
- Soit le setter renvoie autre chose que l'objet (par exemple false) et à ce moment-là la cascade d'instruction est brusquement interrompue par une fatal error. Pas très classe.
- Soit le setter lance une exception et à ce moment-là il faut gérer correctement les exceptions (ce qui n'est pas encore entré dans les habitudes), et surtout pour savoir lequel a fauté dans la liste il faut que chaque setter renvoie une exception à lui, assez chiant à gérer.

Donc le gros point noir c'est la gestion d'erreur, ce n'est pas bloquant, mais c'est un peu moins évident.

ViPHP
ViPHP | 4674 Messages

16 juin 2007, 23:32

Hmm pas bête, j'avais pas pensé à ça.

Et si à la place de lancer une exception, on lançait un objet nul ? Je ne cherche pas une astuce, mais c'est juste par curiosité :P
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

17 juin 2007, 00:39

Un objet nul ? Ça aurait peu de sens de renvoyer un objet qui implémente toutes les méthodes de la classe. Et s'il ne les implémente pas, on aura une fatal error.

Non le plus efficace reste vraiment l'exception, mais il faut le gérer correctement :
try {
    $mail->setBodyText('Ceci est le message.') 
        ->setFrom('[email protected]', 'un expéditeur') 
        ->addTo('[email protected]', 'un destinataire') 
        ->setSubject('sujet de test') 
        ->send();
} catch (ExceptionSetBodyText $e) {
    echo "exception sur setBodyText (erreur de type par exemple)...";
} catch (ExceptionSetFrom $e) {
    echo "exception sur setFrom (adresse e-mail erronée par exemple)...";
} // etc...
Là ce serait propre, et l'avantage c'est qu'on a le choix, soit on gère les exceptions en détails comme là, soit on généralise
try {
   $mail->...
} catch (Exception $e) {
    echo "erreur : {$e->message}";
}
M'enfin de toute façon la vraie question c'est :

entre
$mail->setBodyText('Ceci est le message.') 
    ->setFrom('[email protected]', 'un expéditeur') 
    ->addTo('[email protected]', 'un destinataire') 
    ->setSubject('sujet de test') 
    ->send();
et
$mail->setBodyText('Ceci est le message.');
$mail->setFrom('[email protected]', 'un expéditeur');
$mail->addTo('[email protected]', 'un destinataire');
$mail->setSubject('sujet de test');
$mail->send();
on se crée plus d'ennuis qu'on en résoud non ?

ViPHP
ViPHP | 5924 Messages

17 juin 2007, 01:08

on se crée plus d'ennuis qu'on en résoud non ?
Je plussoie, ce n'est pas naturel, ce n'est pas le rôle de méthodes, et c'est moins pratique.
Et il y a une perte d'informations derrière une telle implémentation...

ViPHP
ViPHP | 4674 Messages

17 juin 2007, 11:17

Qu'on écrive en interface fluide ou non, on doit de toute façon gérer les exceptions.

Tu as fais :
try {
    $mail->setBodyText('Ceci est le message.') 
        ->setFrom('[email protected]', 'un expéditeur') 
        ->addTo('[email protected]', 'un destinataire') 
        ->setSubject('sujet de test') 
        ->send();
} catch (ExceptionSetBodyText $e) {
    echo "exception sur setBodyText (erreur de type par exemple)...";
} catch (ExceptionSetFrom $e) {
    echo "exception sur setFrom (adresse e-mail erronée par exemple)...";
} // etc...
et
try {
   $mail->...
} catch (Exception $e) {
    echo "erreur : {$e->message}";
}
mais de toute façon, la façon de gérer les erreurs se fait comme ça (avec mon Fw) :
try {
    $mail->a()
       ->b()
       ->c()...
} catch ( Hoa_Mail_Exception $e ) {
    $e->raiseError();
}
Hoa_Mail_Exception est une exception (vide en fait) mais qui englobe les exceptions jetés par les mails.


De toute façon, on doit toujours gérer les erreurs et exceptions avec les deux écritures.

Bon, c'était juste pour satisfaire ma curisioté, mais je ne vois pas _vraiment_ où est le problème.

Où est-ce que tu y vois une perte d'informations Sékiltoyai (pas facile à écrire :P)
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 5924 Messages

17 juin 2007, 12:26

Où est-ce que tu y vois une perte d'informations
C'est une perte d'informations dans le sens où la valeur de retour d'une fonction est toujours une information, et si on utilise une telle technique, alors la logique veut qu'on l'utilise pour toutes les méthodes de la classe, et on ne peut donc plus utiliser les valeurs de retour, qui sont des informations.
Sékiltoyai (pas facile à écrire :P)
Je le sais, je le sais :P

ViPHP
ViPHP | 4674 Messages

17 juin 2007, 12:42

Oui mais les interfaces fluides sont étudiées pour les Setter en général, donc la valeur de retour est moins importante.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).