Traits : de la théorie à la pratique

27
Traits : de la théorie à la pratique Rendez-vous AFUP Rendez-vous AFUP 15 décembre 2010 15 décembre 2010 Paris Paris La Cantine La Cantine Frédéric Hardy [email protected] \ http://blog.mageekbox.net \ @mageekguy

Transcript of Traits : de la théorie à la pratique

Page 1: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Rendez-vous AFUPRendez-vous AFUP

15 décembre 201015 décembre 2010

ParisParisLa CantineLa Cantine

Frédéric Hardy

[email protected] \ http://blog.mageekbox.net \ @mageekguy

Page 2: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

À propos du conférencier

● Frédéric Hardy.● 35 ans, marié, 3 enfants.● Développeur PHP depuis plus de 10 ans.● Participe au développement du langage depuis

plus de 5 ans.● Contributeur et développeur de plusieurs

projets libres.● Architecte logiciel chez PMSIpilot à Lyon.

Page 3: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Déroulement de la conférence

● Prés-requis● Résumé de la théorie● Cas pratique● Performances● Comment tester un trait ?● Les inconvénients● Conclusion● Questions

Page 4: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Pré-requis

● PHP ≥ 5.next

● En attendant la sortie de 5.next, il faut utiliser la version de développement de PHP :

# svn export http://svn.php.net/repository/php/php-src/trunk# cd path/to/trunk# ./buildconf# ./configure# make

# make install

● Pour installer la version de développement ou remplacer la version installée :

Page 5: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Résumé de la théorie

● Les traits sont :– Une évolution du modèle objet de PHP.

– Une alternative à l'héritage multiple et au mixin.

● Ils permettent d'éviter la duplication de code.– Via le « copier/coller » de méthodes lors de la

compilation.

● La résolution des conflits est de la responsabilité du développeur.

Page 6: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Cas pratique

● Atoum

– Framework de tests unitaires.

– Utilise à plein PHP 5.3● Fonctions anonyme.● Fermetures.

– Simple et intuitif.● Interface fluide.● Aucune configuration.● Exécution directe.

Page 7: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Comment tester le code suivant ?

Cas pratiqueCas pratique

<?php

namespace vendor\project;

class myClass {public function readFile($file) {

$content = file_get_contents($file);

if ($content === false) {throw new \exception('Unable to read file ' . $file);

}

return $content;}

}...?>

Page 8: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Il y a plusieurs solutions

● Utiliser un système de fichiers :– réel.

– virtuel.

● Utiliser un objet :– Bouchon.

– Adaptateur.

Cas pratiqueCas pratique

Page 9: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Atoum utilise l'adaptateur

Cas pratiqueCas pratique

● L'adaptateur est souple :– Les « fonctions » deviennent « programmables ».

– Le développeur a le contrôle total.

● L'adaptateur est générique :– Il fonctionne avec toutes les fonctions PHP.

● Il permet de contrôler l'ensemble des fonctions PHP sans développement supplémentaire.

● Il est simple à mettre en œuvre.

Page 10: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Le code du test unitaire<?php...class myClassTest extends atoum\test {

public function testReadFile() {$myClass = new \vendor\project\myclass();$myClass->setAdapter($adapter = new atoum\adapter());$adapter->file_get_contents = false;$this->assert

->exception(function() use ($myClass, & $file) {$myClass->readFile($file = uniqid());}

)->isInstanceOf('\runtimeException')->hasMessage('Unable to read file ' . $file)

;}

}...?>

Cas pratiqueCas pratique

Page 11: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Le code de la classe testée<?php...class myClass {

public function setAdapter(atoum\adapter $adapter) {$this->adapter = $adapter;return $this;

}

public function getAdapter() {return $adapter;

}

public function readFile($file) {$content = $this->adapter->file_get_contents($file);...

}}...?>

Cas pratiqueCas pratique

Page 12: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Les conséquences sur le modèle objet

● Il est impossible de prédire les classes qui devront recourir à l'adaptateur.

● Il faut donc dupliquer au besoin dans les classes qui utilise l'adaptateur le code des méthodes :– setAdapter(atoum\adapter $adapter).

– GetAdapter().

Cas pratiqueCas pratique

Page 13: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

● Via la définition d'un trait « adapter ».

– Injectable en fonction des besoins.● Il n'y a plus de duplication de code.

– La maintenance est simplifiée.– Les possibilités d'évolution sont augmentées.

Et si on tirait un trait sur la duplication ?

Cas pratiqueCas pratique

Page 14: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Définition du trait<?php

namespace mageekguy\atoum\traits;

use mageekguy\atoum;

trait adapter {public function setAdapter(atoum\adapter $adapter) {

$this->adapter = $adapter;return $this;

}

public function getAdapter() {return $this->adapter;

}}

?>

Cas pratiqueCas pratique

Page 15: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Utilisation du trait

● Suppression dans les classes concernées de– setAdapter().

– getAdapter().

● Utilisation du trait dans les classes concernées. <?php...abstract class test implements observable, \countable{

use atoum\traits\adapter;...

}...?>

Cas pratiqueCas pratique

Page 16: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Quelques remarques

● Un trait est considéré comme une classe.– L' « autoloading » est donc activé si un trait n'est

pas défini lorsqu'il est appelé.

● Les traits sont compatibles avec les espaces de noms.

● L'appel à un trait via use peut se faire à l'endroit de son choix dans une classe.

● Un trait ne peut hériter d'un autre trait.● Une classe ne peut hériter d'un trait.

Cas pratiqueCas pratique

Page 17: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Performances

Cas pratiqueCas pratique

● Sans trait :

● Avec trait :

> Total tests duration: 2.17 seconds.> Total tests memory usage: 25.75 Mb.> Running duration: 10.87 seconds.> Success (63 tests, 264 methods, 3980 assertions) !

> Total tests duration: 2.15 seconds.> Total tests memory usage: 28.25 Mb.> Running duration: 11.00 seconds.> Success (63 tests, 264 methods, 3980 assertions) !

Page 18: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Comment tester un trait ?

● Un trait ne peut être instancié, il n'est donc pas testable par lui-même.

● Il doit être injecté dans un classe.– Il est donc testable par transitivité.

● Tout comme les méthodes privées et protégées.

● Le support d'un trait par un classe peut être testé à l'aide de l'API d'introspection de PHP.

Page 19: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Les traits et l'API d'introspection

Comment tester un trait ?Comment tester un trait ?

● \reflectionClass::isTrait().

● \reflectionClass::getTraits().

● \reflectionClass::getTraitNames().

● \reflectionClass::getTraitAliases().

Page 20: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Exemple d'utilisation

Comment tester un trait ?Comment tester un trait ?

<?php

$class = new \reflectionClass('\mageekguy\atoum\test');

$traits = $class->getTraits();

var_dump($traits);

foreach ($traits as $trait) {var_dump($trait->getMethods());

}

?>

# vi path/to/reflection.php

Page 21: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Résultat de l'exemple

# path/to/php5.4 path/to/reflection.phparray(1) { ["mageekguy\atoum\traits\adapter"]=> &object(ReflectionClass)#57 (1) { ["name"]=> string(30) "mageekguy\atoum\traits\adapter" }}array(2) { [0]=> &object(ReflectionMethod)#56 (2) { ["name"]=> string(10) "setAdapter" ["class"]=> string(30) "mageekguy\atoum\traits\adapter" } ...}

Comment tester un trait ?Comment tester un trait ?

Page 22: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Tester un trait avec Atoum<?php...class test extends atoum\test {

public function testClass() {$this->assert

->class($this->getTestedClassName())->useTrait('\mageekguy\atoum\traits\adapter')

->trait('\mageekguy\atoum\traits\adapter')->hasMethod('setAdapter')->hasMethod('getAdapter')

;}public function testSetAdapter() {...}public function testGetAdapter() {...}

}...?>

Comment tester un trait ?Comment tester un trait ?

Page 23: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Les inconvénients

● Les traits augmentent l'empreinte mémoire.● L'intégration dans les IDE n'est pas encore

effective.● La relecture du code est plus « laborieuse ».● Ils ne sont disponibles qu'à partir de PHP ≥ 5.4

alors que PHP 5.3 n'est pas encore démocratisé.

Page 24: Traits : de la théorie à la pratique

Traits : de la théorie à la pratique

Conclusion

● Les traits sont une évolution du modèle objet de PHP :– Qui permet de supprimer la duplication de code

– Via un mécanisme de « copier/coller » à la compilation

– Sous le contrôle du développeur

– Simple à mettre en œuvre

– Testable via l'instrospection

– Mais consommatrice de mémoire

– Et qui n'est pas supporté par les IDE.

– Ce qui peut compliquer l'audit du code.

– Et qui n'est pas encore officiellement disponible.

Page 25: Traits : de la théorie à la pratique

25

Traits : de la théorie à la pratique

Questions ?

Page 26: Traits : de la théorie à la pratique

26

Traits : de la théorie à la pratique

Références

● http://wiki.php.net/rfc/horizontalreuse

● http://9elements.com/io/?p=28

● http://blog.mageekbox.net/?post/2010/05/17/Et-si-on-tirait-des-traits

Page 27: Traits : de la théorie à la pratique

27

Traits : de la théorie à la pratique

Remerciements

● Merci à Stephan Marr, pour avoir implémenté les traits dans PHP.

● Merci à l'AFUP pour son invitation.● Merci à PMSIpilot de m'avoir permis de faire

cette conférence.

[email protected] \ http://blog.mageekbox.net \ @mageekguy

Cette conférence est maintenant terminée, vous pouvez reprendre une activité normale.