SlideShare uma empresa Scribd logo
1 de 90
Baixar para ler offline
Caressembleàquoi
FrançoisZaninotto-@francoisz
UneapplicationPHP,quandonarriveà
100000lignesdecode
marmelab-PHPTourLyon2014
Caressembleàça
• Ca ressemble à quoi une appli à cent mille lignes de code ? A ça.
• Une appli à cent mille lignes de code, c’est opaque, poisseux, très dense, et angoissant.
• Une appli à cent mille lignes de code, c‘est surtout trop gros pour qu’on la voit en entier
d’un coup d’oeil.
• C’est le problème de l’éléphant dans la pièce : si vous mettez un éléphant dans une
pièce, vous n’aurez jamais assez de recul pour le voir en entier.
• Il faut donc choisir un angle de vue et accepter une vision partielle - accepter de cacher
des choses. Pour avoir une vision plus globale, il faudra multiplier les points de vue.
• A propos, le nombre de lignes de code, c’est une mesure assez mauvaise de la taille
d’une application. Le nombre de ligne de code peut varier énormément selon les styles
de code. Mais ça peut quand même nous donner un bon ordre de grandeur.
✦ 10loc
✦ 100loc
✦ 1Kloc
✦ 10Kloc
✦ 100Kloc
✦ 1Mloc
✦ 10Mloc
✦ 10loc
✦ 100loc
✦ 1Kloc
✦ 10Kloc
✦ 100Kloc
✦ 1Mloc
✦ 10Mloc
« Hello, world » en PHP (1 loc)
Affichage de la suite de fibonacci (10 loc)
Suite de Fibonacci avec tests (50 loc)
Production moyenne /dev /jour (100 loc)
Gremlins.js (2000 loc)
Monolog (7 800 loc)
Uptime (9 700 loc)
Twig (12 600 loc)
✦ 10loc
✦ 100loc
✦ 1Kloc
✦ 10Kloc
✦ 100Kloc
✦ 1Mloc
✦ 10Mloc
Doctrine (65 kloc)
SwiftMailer (73 kloc)
Photoshop 1.0 (128 kloc)
Symfony2 (180 kloc)
Quake 3 (310 kloc)
Loc poussées sur GitHub par jour (1 Mloc)
CryEngine2 (1 Mloc)
✦ 10loc
✦ 100loc
✦ 1Kloc
✦ 10Kloc
✦ 100Kloc
✦ 1Mloc
✦ 10Mloc
Linux Kernel 2.6.0 (5,9 Mloc)
Firefox (9 Mloc)
Android (12 Mloc)
MySQL (12 Mloc)
Linux 3.1 (15,8 Mloc)
Facebook Frontend (62 Mloc)
OS X Tiger (84 Mloc)
Génôme d’une souris (120 M bases)
✦ 10loc
✦ 100loc
✦ 1Kloc
✦ 10Kloc
✦ 100Kloc
✦ 1Mloc
✦ 10Mloc
Etna
Pourquoic’estimportant
• Etna, le CMS de marmelab, c’est à peu près 2 années homme de développement,
ou 6 mois à 4 développeurs. C’est à peu près 120 000 lignes de code. C’est
l’exemple que je vais utiliser pendant cette présentation pour illustrer mes
propos.
• Que ce soit pour corriger un bug, prendre en charge la TMA, ou refondre le
projet dans son ensemble, vous devrez probablement, dans votre carrière,
rentrer dans une application à 100 000 loc complètement inconnue.
• Et ce jour-là, vous ne serez plus un simple développeur, vous serez un
explorateur de code. Ou un aventurier du code, à la recherche d’un trésor perdu.
• Vous serez…
1-Sesituer
2-Découvrir
3-Faireévoluer
4-Entretenir
1-Sesituer
Sesituer:leproblème
• Imaginez que vous êtes lâché dans une ville inconnue. Les noms de rues sont écrits dans un
alphabet énigmatique. Les habitants parlent une langue incompréhensible.
• Pour tout dire, vous êtes tellementperduquevousavezpeur.
• Arriver sur un projet en cours, lancer un projet de refonte, c’est la même chose que se retrouver
dans une ville inconnue. Et avant toute chose, il faut sesituer.
• Pour se situer, oubliez les détails, il va falloir une vue globale. Une vue de très très haut. Même
sur une base à 100 000 loc, il faut pouvoir vous situer en 10 minutes.
• Un bon truc, pour ça, c’est de réduire le projet à une de ses dimensions, une dimension qui vous
parle. Ca peut être:
• Poids en Kilobits
• Nombre de lignes de code
• Nombre de commentaires
148K%./app/config%
%68K%./app/
DoctrineMigrations%
%92K%./app/Resources%
%56K%./app/tests%
424K%./app%
%%0B%./bin/jar%
%44K%./bin/migration%
8,0K%./bin/tools%
%32M%./bin%
%12K%./config/deploy%
%32K%./config%
%40K%./docs%
7,9M%./src/Etna%
7,9M%./src%
472K%./web/bootstrap%
%56K%./web/components%
156K%./web/css%
%44K%./web/daterangeI
picker%
740K%./web/front%
352K%./web/img%
1,6M%./web/js%
%20K%./web/pnotify%
3,4M%./web%
%48M%.
#%quelle%est%la%taille%du%projet%?%
>%du%Ih%II%'.git'%Id%2%.
du
• Si on prend la taille en Kb comme dimension repère, du, l’utilitaire Linux de
calcul des tailles des fichiers et répertoires sur le disque, est un bon outil.
• Sur Etna, on voit que la plupart du code source est situé sous bin, sous
src, et sous web/js/
• Un rapide examen des répertoires bin et src montre sur des fichiers de
dépendances sont comités dans le repository (Selenium, jQuery). du est
évidemment plus pertinent si on ne commite pas les dépendances. Mais
vous saurez à l’avenir ignorer ces fichiers dans votre exploration.
#%quelle%est%la%taille%du%projet%?%
>%cloc%.%
!
%%%%1630%text%files.%
%%%%1625%unique%files.%
%%%%2076%files%ignored.%
!
http://cloc.sourceforge.net%v%1.58%%T=8.0%s%(167.1%files/s,%21224.6%lines/s)%
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII%
Language%%%%%%%%%%%%%%%%%%%%%%files%%%%%%%%%%blank%%%%%%%%comment%%%%%%%%%%%code%
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII%
PHP%%%%%%%%%%%%%%%%%%%%%%%%%%%%%900%%%%%%%%%%16719%%%%%%%%%%20410%%%%%%%%%%60200%
Javascript%%%%%%%%%%%%%%%%%%%%%%187%%%%%%%%%%%7041%%%%%%%%%%%4764%%%%%%%%%%34299%
CSS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%48%%%%%%%%%%%1599%%%%%%%%%%%%359%%%%%%%%%%12350%
YAML%%%%%%%%%%%%%%%%%%%%%%%%%%%%%65%%%%%%%%%%%%363%%%%%%%%%%%%%36%%%%%%%%%%%3561%
XML%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%22%%%%%%%%%%%%421%%%%%%%%%%%%%65%%%%%%%%%%%2380%
SQL%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%21%%%%%%%%%%%%307%%%%%%%%%%%%363%%%%%%%%%%%2077%
HTML%%%%%%%%%%%%%%%%%%%%%%%%%%%%%57%%%%%%%%%%%%%59%%%%%%%%%%%%%%6%%%%%%%%%%%1033%
Bourne%Shell%%%%%%%%%%%%%%%%%%%%%31%%%%%%%%%%%%204%%%%%%%%%%%%%57%%%%%%%%%%%%605%
XSLT%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%27%%%%%%%%%%%%%55%%%%%%%%%%%%266%
Ruby%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%30%%%%%%%%%%%%%%2%%%%%%%%%%%%128%
Bourne%Again%Shell%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%4%%%%%%%%%%%%%%0%%%%%%%%%%%%%%7%
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII%
SUM:%%%%%%%%%%%%%%%%%%%%%%%%%%%1337%%%%%%%%%%26774%%%%%%%%%%26117%%%%%%%%%116906%
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
cloc
• Si on prend le nombre de lignes de code comme dimension repère, alors le
bon outil c’est cloc.
• cloc est un utilitaire open-source qui compte les lignes de code. Il sait
ignorer les blancs, les fichiers dupliqués, le répertoire .git, il sait
distinguer les commentaires, et divise son total par langage.
• Sur Etna, on voit qu’un bon tiers des lignes de code sont du JavaScript, et
que le ratio code/commentaire est de 3/1 en PHP. C’est plutôt encourageant.
Quellessontlesmassesdecode?
CodeFlower
Oùestlecode,avecplusdedétail?
• Le poids des répertoires à la racine ne suffit pas ; tout est souvent dans lib/ ou dans src/. Il faut
donc approfondir.
• Mais si on descend dans tous les sous-répertoires avec un du ou un cloc , les résultats font des
pages et des pages de texte, c’est inexploitable. Je vous rappelle qu’on n’a que 10 minutes pour se
situer.
• Il faut donc passer à une représentation plus synthétique, une représentation graphique
• Marmelab a travaillé à une visualisation basée sur le résultat d’un cloc sur tous les fichiers d’un
projet. Cette visualisation s’appelle CodeFlower.
• Sur Etna, ça permet de détecter très vite des tendances
• Les gros fichiers qu’il faudra éclater
• Les branches de test qui font écho aux branches de code
• Les répertoires quasi-vides, qui sont souvent le signe de code over-engineeré, à la Java
• Hints: Prendre un repo frais pour éviter dépendances PHP et JS, fichiers générés (cache)
%%1533% Jonathan%Petitcolas%
%%1456% Emmanuel%Quentin%
%%1238% ThieryMichel%
%%1006% Noëlie%Amiot%
%%%473% Olivia%Ly%
%%%315% Daphné%Popin%
%%%197% Simon%Rolland%
%%%187% Eric%Grange%
%%%184% DjebbZ%
%%%177% Francois%Zaninotto
#%qui%travaille%sur%ce%projet%?%
>%git%shortlog%IInumbered%IIsummary%HEAD%|%head%I10
git
• Pour continuer dans la prise de repères rapide, l’historique de Git dispose de
plein d’infos très utiles, comme ici la liste des contributeurs.
• Qui a travaillé sur le code (et donc à qui demander son chemin ?) git
shortlog.
• Quel est l’état du projet ? Git grep. Comme ça utilise la base de données de
git, c’est un grep super rapide qui ignore les fichiers non commités. Mieux
que grep ou ack!
#%quel%est%l’état%du%projet%?%
>%git%grep%Ii%todo%|%wc%Il%
%%%%%%90%
>%git%grep%Ii%fixme%|%wc%Il%
%%%%%%16%
>%git%grep%Ii%todo%
!
app/Resources/views/header.html.twig:%%%%%%%%%%%%{#%@TODO:%display%'.headerIapps'%links%here%in%the%future%#}%
app/Resources/views/layout.html.twig:%%%%{#%@TODO:%add%print.css%and%manage%styles_ie.css%#}%
app/Resources/views/layout.html.twig:%%%%%%%%{#%@TODO:%include%Hot%News%tab%here%#}%
app/config/security.yml:%%%%%%%%#%@TODO%:%find%a%way%to%retrieve%current%locale%
close:app/Resources/views/header.html.twig:%%%%%%%%%%%%{#%@TODO:%display%'.headerIapps'%links%here%in%the%futur%
close:src/Etna/VideoBundle/Resources/views/Video/index.html.twig:{#%@TODO:%apply%.isIactive%on%active%menu%item%
close:web/front/css/layout/_layout.styl:%%%%//%@TODO:%Refactoring%[class="^Ititle"]%pour%tous%les%titres%
close:web/js/ckeditor/plugins/DiagPlWs/core/xslt/correctionUI.xslt:%%%%%%%%%%%%%<!II%TODO%gestion%des%'%II>%
src/Etna/ArticleBundle/Controller/ContentController.php:%%%%%%%%//%@TODO%add%photo%retrieval%to%get%the%credits%
src/Etna/ArticleBundle/Document/Article.php:%%%%%*%@TODO:%implement%it%when%refactoring%article%import/export%
src/Etna/ArticleBundle/Document/Live.php:%%%%%*%@TODO:%implement%it%when%refactoring%article%import/export%
src/Etna/ArticleBundle/Repository/DocumentRepository.php:%%%%%%%%//%@TODO%:%find%a%better%way%to%avoid%paginati%
src/Etna/ArticleBundle/Resources/public/css/tags.css:/**%@TODO%Olivia:%review%this%CSS%to%deal%scrollbar%correc%
src/Etna/ArticleBundle/Resources/views/Content/article_link.html.twig:%%%%{#%@TODO:%apply%correct%style%accordi%
src/Etna/ArticleBundle/Resources/views/Content/content.html.twig:%%%%{#%@TODO:%make%it%dynamic,%according%to%w%
:
Surquelleslibrairiess’appuieleprojet?
DependencyWheel
Etlesdépendances?
• C’est bien joli de visualiser le code comité d’une application PHP, mais à l’époque de composer, le gros
du code servant à l’exécution, cen’estpasvousquil’écrivez. Le gros du code est dans les dépendances.
• Sur Etna, lesdépendancesreprésentent90%ducode nécessaire pour faire tourner l’application.
• Et quand on parle de dépendances, il faut compter les dépendances directes (dans le
composer.json) et indirectes (dépendances des dépendances, qu’on trouve dans le
composer.lock).
• Pour visualiser les dépendances directes et indirectes, on a développé une autre visualisation qui
s’appelle DependencyWheel
• Sur Etna, on s’aperçoit que le composer.lock liste 47 librairies, mais qu’au final, en comptant les
dépendances externes, il en faut 105 pour faire tourner l’application.
• On voit même des dépendances inattendues. C’est un projet sous Symfony, mais je vois des
composants Zend dans les dépendances. Mais pourquoi télécharger des librairies qui font le travail en
double des composants Symfony?
N’oubliezpas
JSetCSS
N’oubliezpasleJSetleCSS
• De plus en plus de code est déporté côté client. Visualiser le code PHP, ça ne
suffit pas !
• C’est en JS et en CSS qu’on trouve les plus gros fichiers.
• jQuery et Bootstrap sont souvent commités malgré bower, mais ce n’est pas le
plus significatif. En fait, ces librairies ne font pas partie de votre code.
• On n’a pas encore une approche aussi modulaire en CSS et JS qu’en PHP et HTML.
• Mais ce n’est pas le sujet de cette conf
✓ Sesituer
Conclusion
• En dix minutes, avec quelques commandes bash, deux graphes, et un peu
d’astuce, le jeune développeur explorateur n’est déjà plus perdu. Il sait où il
se trouve et à qui il a affaire.
• Il peut désormais partir serein à la découverte des secrets du code qui
recèlent peut-être un trésor perdu.
• Mais il n’est pas au bout de ses surprises !
2-Découvrir
2-Découvrir
• Passée l’angoisse de l’inconnu, une fois que qu’il a réussi à corriger le premier bug,
l’explorateur de code cherche à mieuxcomprendre cette application à 100 000 lignes
de code.
• Il commence à s’éloignerunpeu du code qu’il connait, il s’aventure dans des classes
qu’il n’a jamais ouvertes.
• Quel est le rôle de cette classe ? Avec qui communique-t-elle ? Comment s’inscrit-elle
dans le système ? Les questions sont déjà d’un ordre plus logique que physique.
• Declasseenclasse, l’explorateur de code va découvrir l’ensemble de l’application. Il va
se l’approprier. Il va l’apprivoiser.
• Il lui faut juste un guide pour ne pas se perdre. Un guide, ou une carte, et un annuaire.
#%que%fait%cette%classe?%
>%phpunit%Ic%app%—filter%ContentLocker%—testdox%
!
EtnaArticleBundleServiceContentLocker%
%[x]%Lock%content%should%persist%a%lock%
%[x]%Lock%content%should%be%set%with%correct%data%
%%%%%when%persisted%
%[x]%Lock%content%should%not%be%persisted%if%
%%%%%already%exists%
%[x]%Unlock%content%should%remove%content%lock%
%[x]%Is%locked%content%should%return%true%if%%
%%%%%content%is%locked%
%[x]%Is%locked%content%should%return%false%if%%
%%%%%content%is%not%locked
Lestestsunitaires
• De manière peut-être inattendue, le premier guide à interroger, ce sont les tests
unitaires.
• Les tests décrivent cequ’uneclassedoitfaire. Ils décrivent aussi ce qu’une classe
n’arrive plus à faire quandonlacasse. Ils sont donc forcément présent dans une
application à 100 000 lignes de code (sinon elle n’est pasmaintenable).
• Le compte-rendu des tests, il est facile à lire - pour peu qu’on utilise le bon
formatage.
• phpUnit propose le format testdox pour générer une documentation agile à
partir des tests unitaires. Vous voyez ici ce qu’ils peuvent nous apprendre sur
une classe précise (ciblée par l’option —filter)
<?php%
class%ContentLockerTest%extends%PHPUnit_Framework_TestCase%
{%
%%%%public%function%testLockContentShouldPersistALock()%
%%%%{%
%%%%%%%%//%...%
%%%%}%
!
%%%%public%function%testLockContentShouldBeSetWithCorrectDataWhenPersisted()%
%%%%{%
%%%%%%%%//%...%
%%%%}%
!
%%%%public%function%testLockContentShouldNotBePersistedIfAlreadyExists()%
%%%%{%
%%%%%%%%//%...%
%%%%}%
}
Lestestsunitaires
• Pour avoir ce joli rendu en « testdox », il faut nommer les méthodes de test
avec une phrase explicite, sujet-verbe-complément, et joindre tous les mots
écrits en CamelCase.
• Gros avantage des tests automatisés: ils sont nécessairement à jour avec le
code, sinon ils ne passent pas.
• Les tests; c’est bien, mais dites-moi: ce n’est pas le rôle de la documentation
de nous aider à découvrir l’inconnu sans trop se mouiller ?
Etladoc?
LaDoc
• La documentation, ça prend du temps, c’est obsolète dès qu’on modifie le code, et
puis c’est dur à écrire. Par conséquent, soyons honnêtes, autant ne pas en écrire, de
documentation.
• L’un des préceptes de l’agilité nous dit D’ailleurs : ladocumentation,c’estlecode
(« Code as craft »)
• Par exemple, si vous utilisez l’injection de dépendance, le constructeur d’une classe
vous renseigne tout se suite sur les relation qu’elle a avec d’autres classes.
• Pour que le code serve de documentation, il faut qu’il soit lisible. Le code est écrit
pour être lupar2choses : le serveur qui l’exécute, et le développeur qui le débuggue.
• Travaillez bien votre code pour le rendre lisible et éviter d’avoir à écrire de la
documentation. A mon sens, c’est bien plus utile à long terme.
Sanscommentaire
Lescommentaires
• Juste un petit aparté sur un malentendu. Quand ils entendent « code as craft »,
certains développeurs se disent qu’il suffit de barder le code de commentaires.
• Ca, souvent, ça ne sert à rien. Je pense par exemple à la phpDocparaphrase, du genre
« getPrice : returns the price ».
• Un code avec plein de commentaires comme ça, c’est un déguisement. Mais ça ne fait
pas illusion. Il suffit de le regarder de plus près pour s’apercevoir qu’il n’est pas plus
lisible pour autant.
• Les bons usages des commentaires, pour moi, c’est quandlecodeneditpastout, ou
que la lecture du code pose des questions. Ca doit vraiment être un complément.
• A mon, sens, un code bien écrit a souvent assez peu de commentaires - disons une
lignedecommentairepour20lignesdecode. C’est qu’un code bien écrit est son propre
commentaire. Un code bien écrit est sa propre documentation.
%%%%/**%
%%%%%*%Returns%the%price%
%%%%%*%
%%%%%*%@param%TaxRule%$tax%The%tax%rule%
%%%%%*/%
%%%%public%function%getPrice(TaxRule%$tax)%
%%%%{%
%%%%%%%%//%...%
%%%%}%
EtlaDocAPI?
Fairelepoint,dresserl’inventaire
• Après avoir vu des méthodes pour comprendre ce que fait une classe, il est
temps de chercher des moyens de comprendre des ensembles plus grands.
Pour cela, il faut dresser l’inventaire du projet.
• On a déjà fit un inventaire des fichiers avec CodeFlower. Mais c’est un
inventairephysique. Ce qu’il faut pour découvrir l’application, c’est un
inventairelogique, un inventaire des classes et des méthodes.
• Cette liste, on appelle ça la DocAPI. Pour le générer, je vous conseille Sami, un
utilitaire de Fabien Potencier qui crée un dictionnaire HTML à partir d’une
base de code PHP.
Quefaitcetteclasse?
Sami
Readthesource,luke
• Mais en fait, je trouve que ça ne sert pas à grand chose. La doc API s’adresse à
un lecteur humain, mais je vous ai déjà proposé plus haut d’écrire votre code
justementpourqu’ilsoitlisibleparunhumain.
• Si une doc API sert à trouver le détail d’une classe en tapant son nom, un IDE
sait déjà faire ça. Avec Command+T, sur SublimeText, je trouve la classe que je
veux en tapant des bouts de son nom.
• Votre IDE sait également vous éviter carrément la recherche en proposant de
l’autocompletion, et des typehints sur les paramètres d’appels à une méthode.
• Pour faire le point, pas besoin donc d’une doc API à mon avis. Utilisez les
indexes déjà à votre disposition, ceux de votre IDE.
Dequoidépenduncomposant?
ArchitectureTree
Représenterl’architecture
• Au fur et à mesure de la découverte, nous sommes passés du plan physique (fichiers, lignes de code), au plan
logique (classes, méthodes, interfaces).
• Mais pour comprendre en profondeur l’architecture d’une application, il faut passer au plan conceptuel
(domaine, entités, relations, aggrégats).
• L’idéal dans ce cas, c’est de disposer d’un schémad’architecture. Mais s’il existe, c’est souvent comme pour la
documentation: il est déjà obsolète. Sans compter qu’il faut Visio ou OmniGraffle pour pouvoir l’éditer, ce que
seuls un ou deux postes dans votre entreprise permettent.
• La solution : un schéma d’architecture en HTML5, basé sur un fichier texte, éditable par tous les développeurs.
• L’objectif, c’est de tout faire tenir en un seul graphe. Forcément, certaines informations (briques techniques,
hébergement) ne se révèleront qu’au rollover.
• On l’a appelée: ArchitectureTree. Cela permet de prendre un maximum de hauteur et d’identifier efficacement à
la fois les composants de l’application, et leurs relations.
• Ce n’est pas encore open-source !
{%"name":%"SaaS",%
%%"children":%[%
%%%%%%{%"name":%"Xiti"%},%
%%%%%%{%"name":%"Imaging",%
%%%%%%%%"children":[%
%%%%%%%%%%{%"name":%"Horby",%
%%%%%%%%%%%%"technos":%["Python",%"ElasticSearch"],%
%%%%%%%%%%%%"dependsOn":%["Krakatoa"]%},%
%%%%%%%%%%{%"name":%"Hoor",%
%%%%%%%%%%%%"technos":%["Python"],%
%%%%%%%%%%%%%"dependsOn":%["Photos",%"Horby",%"Photos"]%},%
%%%%%%%%%%{%"name":%"Dale",%
%%%%%%%%%%%%"technos":%["Python"],%
%%%%%%%%%%%%"dependsOn":%["Horby"]%},%
%%%%%%%%%%{%"name":%"Krakatoa",%
%%%%%%%%%%%%"technos":%["Silex"],%
%%%%%%%%%%%%"dependsOn":%["Photos"],%
%%%%%%%%%%%%"satisfaction":%0.5%},%
%%%%%%%%%%{%"name":%"Stockholm",%
%%%%%%%%%%%%"technos":%["Python"],%
%%%%%%%%%%%%"dependsOn":%["Photos"],%
%%%%%%%%%%%%"satisfaction":%0.2%}%
%%%%%%%%%%]},%
%%%%%%{%"name":%"Katla",%
%%%%%%%%"comments":%"Node.js%application%to%gather%social%counts%on%Etna%contents",%
%%%%%%%%"technos":%["Node.js"]%},%
%%%%%%{%"name":%"Netino",%
%%%%%%%%"comments":%"Comment%moderation%service",%
%%%%%%%%"technos":%["SOAP"]%}%
%%]%
}
ArchitectureTree:lasource
• Voici le format JSON utilisé pour alimenter le graphe.
• Il décrit, pour chaque noeud du graphe, un nom, des attributs, des
dépendances, et des enfants.
• C’est facile à éditer par n’importe qui, et le graphe HTML5 s’en nourrit en
direct. Il suffit de faire F5 après avoir mis à jour le fichier.
• Le graphe peut même être hébergé sur une branche gh-pages sur GitHub
pour montrer en permanence l’état de l’architecture.
✓Découvrir
Conclusion
• Avouez que cette application de 100 000 lignes de code, elle nevousfaitdéjàplus
peur.
• Avec une bonne carte, un IDE efficace, des tests unitaires, et potentiellement un peu
de documentation, l’application commence même, en général, à donnerenvie au
développeur.
• Incidemment, ces outils permettent de découvrirdeschosesqu’onnecherchaitpas.
Comme quand on regarde une carte en se disant : « Chéri, tu savais qu’il y a une usine
Seveso à 500 mètres de la maison ? ». Les anglo-saxons parlent de serendipity, ce
que Google traduit par « don de faire des découverte accidentelles ».
• Bon, mais maintenant il va falloir rentrer dans la carte et s’immerger complètement.
Maintenant, c’est l’heure de l’aventure.
3-Faireévoluer
3-Faireévoluer
• L’aventure, c’est defaireévoluer cette application de 100 000 lignes de code.
• C’est ce qu’on vous demande touslesjours. « Tu pourrais ajouter un module de recommandation en direct, tu
sais, basé sur l’historique de navigation, et sur les clients qui ont des goûts similaires ? »
• Tous les jours, sur une application à 100 000 lignes de code, on demande aux développeurs d’ajouter
davantagedelignesdecode. Là où c’est une vraie aventure, c’est qu’on ne demande jamais d’ajouter du code
qui existe déjà. Il faut le découvrir, l’inventer, ce code.
• Commentimplémenterunenouvellefonctionnalité ? Dans quel répertoire mettre une classe ? Comment
nommer les fichiers, les méthodes, les services ?
• Ce n’est pas le tout de connaître l’application, il faut savoir la modifier à la demande, et trouverlebonchemin
d’implémentation.
• En évitant au passage, les bugs, les trous de sécurité, les problèmes de performance, et les coupeurs de
tête.
• Vous vous sentez toujours l’âme d’un aventurier ? Allons-y.
DesignPatterns
DesignPatterns
• Pour s’engager en territoire hostile, il faut un peu de préparation. Recruter un bon guide, calculer
son itinéraire, s’informer des coutumes locales.
• Pour implémenter une fonctionnalité, c’est pareil. Avant même de démarrer, vous savez que vous
aurez à router vers une action, injecter un service, persister une entité, afficher un template.
• Ces stratégies d’implémentation, ces routes privilégiées, ce sont des design pattern.
• Vous en connaissez tous un certain nombre: ActiveRecord, Adapter, Visitor, Template, Front
Controller, MVC, Dependency Injection.
• Ils ont été conçus par de vieux routards du code et ils nous aident à nous concentrer sur la
logique métier sans réinventer la roue.
• Le développeur explorateur, avant de partir, potasse sa littérature. Il révise son Martin Fowler et
son Eric Evans. Lisez-les vous aussi, sinon votre PHP risque de n’être qu’un gros tas de spaghetti
que vous serez le seul à comprendre, et qui ne vous mènera nulle part.
Fullstack
Framework
UtiliserunFrameworkfull-stack
• D’ailleurs, plutôt que d’essayer d’implémenter le pattern MVC tout seul, il vaut mieux
utiliserunframework qui le fait déjà.
• Et pas un microframework. On parle d’une application à 100 000 lignes de code ! Un
microframework, ça amène péniblement à 10 000 lignes de code maximum.
• Et pas un framework propriétaire non plus. On n’est plus en 2004. Si on peut éviter
d’avoir à réapprendre une nouvelle manière de gérer les requêtes HTTP, l’accès à la
base de données, la validation des formulaires, c’est toujours ça de gagné.
• Il faut donc un framework full-stack, open-source, et avec une grosse communauté.
• Dans le projet à 100 000 lignes de code dont je vous parle aujourd’hui, on a utilisé
Symfony2.
Bonnespratiques
Bonnespratiques
• Mais utiliser Symfony2, ça ne suffit pas pour savoir précisément où mettre le code. Pour cela, il faut connaitre les
bonnes pratiques.
• Fat model, Skinny controllers, Separation of concerns, DRY. Je ne vais pas les expliquer ici, mais c’est quand on les
applique sur une grosse base de code qu’elles prennent tout leur sens.
• Elles nous permettent de répondre à la question «  mais où mettre ce code ? » Question d’autant plus pertinente si
l’application fait déjà 100 000 lignes de code.
• Attention, les bonnes pratiques ne sont pas toujours celles qu’on croit.
• Je vous donne un exemple. Dans Symfony, la plupart du code source est sous src/, regroupé en « bundles », qui sont
des sortes de modules.
• Sur Etna, On a fait un bundle par groupe fonctionnel. Vous savez quoi ? C’est une mauvaise idée.
• On s’y perdait, du code nécessaire à une fonctionnalité était éclaté dans 2 bundles, les services d’un Bundle devenaient
dépendants des services des autres Bundles…
• On n’aurait du faire qu’un seul bundle, et mettre la logique métier indépendante du framework dans des répertoires à
part. Ca, on s’en est rendus compte trop tard.
>%ls%src/Etna%
!
AdminBundle%%%%%%%%%%%OriginBundle%
ArticleBundle%%%%%%%%%SurveyBundle%
FrameworkBundle%%%%%%%TagBundle%
FrontUserBundle%%%%%%%TrackingBundle%
HpeBundle%%%%%%%%%%%%%UserBundle%
MiscBundle%%%%%%%%%%%%VideoBundle%
NotificationBundle
>%ls%src/Etna%
!
Article%%%%%%%%%%%%%%%Survey%
EtnaBundle%%%%%%%%%%%%Tag%
FrontUser%%%%%%%%%%%%%Tracking%
HPE%%%%%%%%%%%%%%%%%%%User%
Notification%%%%%%%%%%Video%
Origin%
Lebonnom
Thereareonlytwohard
thingsinComputerScience:
cacheinvalidationand
namingthings.
!
PhilKarlton
Lebonnom
• Bien nommer les classes et ses méthodes, c’est 50% du travail.
• S’il est choisi trop vite, un nom peut créer de gros malentendus, avec de
lourdes conséquences.
• Vous connaissez sans doute la citation de Phil Karlton. Trouver le bon nom,
en informatique, c’est une des choses les plus dures qu’il soit.
• En même temps, Phil Karlton est mort en 1997, il n’a pas pu connaitre
Doctrine. Mais je m’égare.
• Pour organiser une grosse base de code, nommer correctement ses classes,
modules et agrégats, c’est fondamental.
ArticleManager%
TagTools%
TrackingUtils%
NotificationService
Entities% % % % % Services%
Article%% % % % % ContentLocker%
Notification%% % ArticleCleaner%
Lock% % % % % % % SurveyParser%
TagRepository%% % UrlGenerator%
Link% % % % % % % LiveImporter%
!
Framework%classes%I%almost%empty%
MediaFormType%
LegacyIdListener%
CleanContentCommand%
ProfileAdminController%
BreadcrumbTwigExtension
DéfinirdesStandardsdenommage
• Voici des exemples de mauvais noms. Ces noms sont des odeurs de code. Toutes vos classes,
en cherchant bien, peuvent être renommées « manager ». C’est un peu comme dans
l’organisation des grandes entreprises, tout le monde est responsable de quelque chose.
• Le bon nom, il vient du domaine. Le bon nom, c’est celui qui est employé par le client dans son
travail de tous les jours. Nommez une chose pour une entité, une action (avec un verbe)
pour un service.
• Le Domain-Driven-Design, c’est le nom d’un bouquin d’Eric Evans sur les Design Patterns, Le
Domain-Driven Design parle de « Langage omniprésent » (ubiquituous language). Ce
langage, ces noms, sont une des clés de l‘évolution d’une grosse application.
• Et si le Framework que vous utilisez vous impose d’écrire des classes hors du domaine,
mettez-y le moins de choses possibles. Ces classes-là doivent s’appuyer sur les classes du
domaine.
Respecterles
standards
#!/bin/sh%
#%in%.git/hooks/preIcommit%
!
PROJECTROOT=`echo%$(cd%${0%/*}/../../%&&%pwd%IP)`/%
!
RES=`phpIcsIfixer%fix%$PROJECTROOT%IIverbose%IIdryIrun`%
if%[%"$RES"%!=%""%];%then%
% echo%"Committed%code%is%not%PSRI2%compliant,%cancelling%your%commit."%
% echo%$RES%
% echo%"If%you%want%to%fix%them%run:"%
% echo%"%%%%phpIcsIfixer%fix%${PROJECTROOT}%IIverbose"%
% exit%1%
fi% %
!
Standarddecodage
• Un projet de 100 000 lignes de code, c’est au moins 4 développeurs pendant 6 mois. Ca
fait donc pasmaldemonde qui passe sur l’appli
• Si chacun a sa propre manière de coder, ça devient très vite un beau sacdenoeuds.
• A ce niveau, on ne peut pas se passer de standarddecodage
• C’est un peu le « code de la route », les panneaux d’interdiction / d’obligation. Une
manière astucieuse d’éviter les accidents.
• Utilisez des standards existants, là encore pour éviter un délai de mise en route pour les
nouveaux arrivants. En PHP, les standards se nomment PSR-0 et PSR-2.
• Mais c’est une tâche qu’on sait très bien automatiser. N’embêtez pas vos développeurs
avec ça, mais faites un post-commit hook avec un php9cs9fixer qui propose des
changements et modifie le dernier commit en cas d’écart.
✓Faireévoluer
Conclusion
• Plus la base de code est grosse, plusilfautdesrègles pour en forcer l’organisation, plus il faut des
panneaux pour ne pas s’égarer.
• Design patterns, frameworks full-stack, bonnes pratiques, dictionnaire du domaine, standards de
codage, tout cela devient obligatoires dès que deux personnes travaillent sur la même base de code.
• Du coup, une appli PHP de 100 000 lignes de code ressemble normalement beaucoup à toutesles
autresapplisPHPde100000lignesdecode.
• Pour un développeur qui a déjà travaillé sur un projet de cette taille, le faire évoluer n’est qu’une
formalité. Le plus difficile, c’estlapremièrefois.
• Fixer des règles, ce n’est pas une raison pour devenir dogmatique. Ces règles sont faites pour
minimiser le coût d’implémentation. Si vos règles augmentent significativement le temps
d’implémentation, changez -les.
4-Entretenir
4-Entretenir
• Une grosse base de code, ça s’entretient, ça se bichonne.
• Ca ne suffit pas de lui ajouter des nouvelles fonctionnalités, il faut la
refactorer en permanence.
• Mais par où commencer ? Qu’est-ce qui est prioritaire ?
• Vu le volume, un audit de code manuel n’est pas possible. En plus, il faut être
capable d’évaluer la qualité en continu.
• Là encore, il va falloir trouver de bons outils.
Ladette
technique
Ladettetechnique
• On développe tous sous contraintes, on ne peut pas faire un code parfait. D’ailleurs,
ce serait en pure perte, puisque les besoins évoluent. Un code parfait est un code
de luxe.
• Donc, le code s’écarte constamment de la qualité nominale. Cet écart, on l’appelle
« dette technique », et on le mesure en temps de développement nécessaire pour
la compenser. Par example: « Ma dette technique est de 3 jours sur cette librairie »
signifie qu’il faut travailler 3 jours pour atteindre un niveau de qualité nominale.
• Cette dette traduit les écarts de performance, de sécurité, de robustesse, de
maintenabilité, de lisibilité avec le meilleur niveau communément admis.
Quelssontlespointsfaibles?
SensioLabsInsight
SensioLabsInsight
• Quelques outils d’analyse automatique permettent d’évaluer la dette technique: PHP CodeSniffer,
PHP_MD, PHP_Depend, Le meilleur dans le monde PHP/Symfony, c’est actuellement Insight, de SensioLabs.
• Certaines violations proposent même un script de résolution. Y’a pas plus facile pour améliorer la
qualité. Si vous êtes sur GitHub, chaque violation permet d’ouvrir un ticket.
• Sur Insight, la dette technique s’appelle « coût de remédiation ». Cela donne un très bon aperçu du
niveau de qualité d’un projet.
• Evidemment, plus il y a du code, plus la dette technique est haute.
• On a pu faire des statistiques sur plein de projets Insight. En moyenne, le coût de remédiation d’un
projet est de 1 minute pour 1 ligne de code.
• Donc un élément encore plus représentatif que le coût de remédiation, c’est le rapport entre le coût de
remédiation et le nombre de lignes de code. Insight le calcule, et ça donne le score des projets - c’est
tout nouveau !
Paroùcommencer?
ViolationSunburst
Visualiserladettetechnique
• Sur un gros projet, la dette technique s’élève souvent à plusieursmois. Un outil de
contrôle qualité comme Insight révèle facilement plusieurscentaines de violations.
• A nouveau, on a besoin d’une visualisation pour synthétiser ces résultats, détecter
les points d’attention principaux, les tendances dans le code, mais cette fois du point
de vue de la qualité.
• Insight relie certaines violations (pas toutes) à un fichier. L’ensemble des violations
d’un fichier donné définit ladettetechniquedecefichier. Ca donne une bonne visibilité
de là où les efforts d’entretien doivent se concentrer.
• On a mis tout ça sur un graphe qu’on a appelé ViolationSunburst. On a choisi d’utiliser
lacouleurpourreprésenterlasévéritédesviolations comprises dans un répertoire. Plus
c’est rouge, plus c’est critique.
Nepasoublier
Ladimensiontemporelle
• Les problèmes de qualité, on a tendance à les oublier facilement. Comme c’est souvent secondaire,
on les relègue dans un coin de notre tête pour plus tard, mais il y a toujours plus urgent.
• Le résultat, c’est que notre code recèle des bombes à retardement.
• Un bon moyen de repérer ces bombes, c’est de repérer les fichiers qui n’ont pas été ouverts depuis
longtemps. Ce sont ceux susceptibles de cacher des risques graves, parce qu’on a déjà bâti des
choses dessus.
• Un autre moyen de repérer les bombes, c’est de voir combien de fois un fichier a été modifié. Plus
il y a de modifications, plus le fichier concerne une classe complexe qui a évolué, et plus il y a de
risques.
• Toutes ces informations (date de dernière modification, nombre de modifications), votre repo Git
les a. Il suffit de les mettre en forme pour les exploiter.
• C’est ce qu’on a fait avec une dernière visualisation nommée ArcheoloGit.
Qu’est-cequipeutcasser?
ArcheoloGit
✓Entretenir
Conclusion
• Entretenir une appli de 100 K loc, c’est du travail
• La dette technique s’accumule à chaque développement, sachez l’évaluer et lui donner une
consistance visuelle.
• Insight, ViolationSunburst et ArcheoloGit sont de bons outils pour ça.
• ils peuvent vous aider à convaincre le product owner d’investir de temps à autre pour éponger cette
dette.
• Faute de quoi, l’application va devenir inmaintenable, les temps de debug vont s’allonger, le temps
d’implémentation d’une nouvelle fonctionnalité va exploser.
• En pratique, pour une appli de cette taille, il faut consacrer au moins 1 ETP à l’entretien de
l’application pour éviter une dérive néfaste du niveau de qualité
Conclusion
1MillionLOC
Conclusionfinale
• A quoi ça ressemble une appli de 100 000 ligne de code ? Cadépend de quel côté on regarde.
• J’espère vous avoir donné des outilsetdesvisualisations pertinentes pour mieux vous situer, découvrir, faire évoluer et
entretenir une base de code de cette taille.
• J’espère surtout vous avoir convaincu de changerpointdevue de temps à autre, de prendredelahauteur pour mieux
distinguer les lignes de force.
• Entretenir une telle application, c’est un travaild’équipe. Partagez vos visualisations avec toute l’équipe de
développement pour qu’ils les fassent vivre. Cultivez la propriétécollectiveducode pour éviter les bombes à retardement.
• On arrive assez vite à 100 000 lignes de code sur un projet de 6 mois - 1 an. Vous aurez à utiliser ces outils.
• Le problème, c’est que tous les outils que je vous ai montrés ne fonctionnent plus quand on passe au degré suivant,
quand on passe à 1 Millions de loc
• Ce n’est pas tant la faute des outils, c’est juste que ça devient très difficile de se situer, de découvrir, de faire évoluer et
d’entretenir une application d’1 million de lignes de code.
• D’ailleurs, une application peut très bien mourir de trop de code. Mais alors, par quoi remplacer une application de plus de
100 000 lignes de code quand elle grossit trop ?
Microservices
Microservices
• Prenez l’exemple de Linux. 15 millions de lignes de code qui restent maintenables parce que les
développeurs produisent des composants indépendants, simples et interopérables.
• The Unix Philosophy (1994)
Write programs that do one thing and do it well. Write programs to
work together. Write programs to handle text streams, because that is
a universal interface.
• Dans le web, on peut interfacer les programmes un peu plus finement grâces aux services HTTP, ou aux
files AMQP.
• Alors, évitez les très grosses applications, et visez toujours une architecture orientée services (SOA, ou
microservices depuis 2014)
• A qui ça ressemble une application à 1 million de lignes de code ?
• Si c’est une application qui a survécu, c’est forcément plusieurs applications de 100 000 lignes de code,
découplées, plus faciles à comprendre et à maintenir.
Merci
Cloc http://cloc.sourceforge.net/
CodeFlower https://github.com/fzaninotto/CodeFlower
DependencyWheel https://github.com/fzaninotto/DependencyWheel
Sami https://github.com/fabpot/sami
ArchitectureTree pas encore public
Domain-Driven Design http://amzn.com/0321125215
PSR-2 https://github.com/php-fig/fig-standards
Insight https://insight.sensiolabs.com/
ViolationSunburst pas encore public
ArcheoloGit https://github.com/marmelab/ArcheoloGit
Visualisations http://d3js.org/
Illustrations Steven et Georges
FrançoisZaninotto-@francoisz

Mais conteúdo relacionado

Mais procurados

Synchroniser ses applications plus rapidement avec du low-code
Synchroniser ses applications plus rapidement avec du low-codeSynchroniser ses applications plus rapidement avec du low-code
Synchroniser ses applications plus rapidement avec du low-codegplanchat
 
Devoxx 2017 : toutes les actualités technologiques à surveiller !
Devoxx 2017 : toutes les actualités technologiques à surveiller !Devoxx 2017 : toutes les actualités technologiques à surveiller !
Devoxx 2017 : toutes les actualités technologiques à surveiller !Société ELOSI
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetupSamir Rouabhi
 
Synchroniser ses applications (plus) simplement
Synchroniser ses applications (plus) simplementSynchroniser ses applications (plus) simplement
Synchroniser ses applications (plus) simplementgplanchat
 
AT2010 Principes Integration Continue
AT2010 Principes Integration ContinueAT2010 Principes Integration Continue
AT2010 Principes Integration ContinueNormandy JUG
 
Hibernate vs le_cloud_computing
Hibernate vs le_cloud_computingHibernate vs le_cloud_computing
Hibernate vs le_cloud_computingIppon
 
Quid de vos applications symfony 1
Quid de vos applications symfony 1Quid de vos applications symfony 1
Quid de vos applications symfony 1marchugon
 
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Ippon
 
Breizhjug spring batch 2011
Breizhjug spring batch 2011Breizhjug spring batch 2011
Breizhjug spring batch 2011Olivier BAZOUD
 
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...Alexis Kinsella
 
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016Fabien Arcellier
 
TypeScript for dummies
TypeScript for dummiesTypeScript for dummies
TypeScript for dummiesMicrosoft
 
Développez dans le futur, dès maintenant !
Développez dans le futur, dès maintenant !Développez dans le futur, dès maintenant !
Développez dans le futur, dès maintenant !Mathieu Parisot
 
NodeJs, une introduction
NodeJs, une introductionNodeJs, une introduction
NodeJs, une introductionToxicode
 
Perfug BOF devoxx2017.pptx
Perfug BOF devoxx2017.pptxPerfug BOF devoxx2017.pptx
Perfug BOF devoxx2017.pptxMarc Bojoly
 

Mais procurados (20)

Spring Batch ParisJUG
Spring Batch ParisJUG Spring Batch ParisJUG
Spring Batch ParisJUG
 
Synchroniser ses applications plus rapidement avec du low-code
Synchroniser ses applications plus rapidement avec du low-codeSynchroniser ses applications plus rapidement avec du low-code
Synchroniser ses applications plus rapidement avec du low-code
 
The Future of Javascript
The Future of JavascriptThe Future of Javascript
The Future of Javascript
 
Devoxx 2017 : toutes les actualités technologiques à surveiller !
Devoxx 2017 : toutes les actualités technologiques à surveiller !Devoxx 2017 : toutes les actualités technologiques à surveiller !
Devoxx 2017 : toutes les actualités technologiques à surveiller !
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetup
 
Synchroniser ses applications (plus) simplement
Synchroniser ses applications (plus) simplementSynchroniser ses applications (plus) simplement
Synchroniser ses applications (plus) simplement
 
AT2010 Principes Integration Continue
AT2010 Principes Integration ContinueAT2010 Principes Integration Continue
AT2010 Principes Integration Continue
 
Hibernate vs le_cloud_computing
Hibernate vs le_cloud_computingHibernate vs le_cloud_computing
Hibernate vs le_cloud_computing
 
Quid de vos applications symfony 1
Quid de vos applications symfony 1Quid de vos applications symfony 1
Quid de vos applications symfony 1
 
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
 
Breizhjug spring batch 2011
Breizhjug spring batch 2011Breizhjug spring batch 2011
Breizhjug spring batch 2011
 
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...
Devoxx france 2015 - Intégrer et exploiter le format de données ouvert GTFS. ...
 
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016
Infra as Code, choisissez vous la pilule rouge ou la pilule bleue - Devoxx 2016
 
Networxx (intro et fin)
Networxx (intro et fin)Networxx (intro et fin)
Networxx (intro et fin)
 
TypeScript for dummies
TypeScript for dummiesTypeScript for dummies
TypeScript for dummies
 
Développez dans le futur, dès maintenant !
Développez dans le futur, dès maintenant !Développez dans le futur, dès maintenant !
Développez dans le futur, dès maintenant !
 
Spring Batch - concepts de base
Spring Batch - concepts de baseSpring Batch - concepts de base
Spring Batch - concepts de base
 
Ansib formation-ansible
Ansib formation-ansibleAnsib formation-ansible
Ansib formation-ansible
 
NodeJs, une introduction
NodeJs, une introductionNodeJs, une introduction
NodeJs, une introduction
 
Perfug BOF devoxx2017.pptx
Perfug BOF devoxx2017.pptxPerfug BOF devoxx2017.pptx
Perfug BOF devoxx2017.pptx
 

Destaque

EmpowerLA - Election 2014 - Timeline - Region 1
EmpowerLA - Election 2014 - Timeline - Region 1EmpowerLA - Election 2014 - Timeline - Region 1
EmpowerLA - Election 2014 - Timeline - Region 1EmpowerLA
 
Informe gestión ambiental CDMC 2016
Informe gestión ambiental CDMC 2016Informe gestión ambiental CDMC 2016
Informe gestión ambiental CDMC 2016Camila RIVERA
 
Sistema Integrado de Gestión y Autocontrol
Sistema Integrado de Gestión y AutocontrolSistema Integrado de Gestión y Autocontrol
Sistema Integrado de Gestión y AutocontrolCamila RIVERA
 
Qualité de code, sonar, la dette
Qualité de code, sonar, la detteQualité de code, sonar, la dette
Qualité de code, sonar, la detteNovencia Groupe
 
Polígono e Padrões
Polígono e PadrõesPolígono e Padrões
Polígono e PadrõesMarcio Duarte
 
Desenho técnico básico - Camiseta Regata
Desenho técnico básico - Camiseta RegataDesenho técnico básico - Camiseta Regata
Desenho técnico básico - Camiseta RegataMarcio Duarte
 
Conhecendo o CorelDRAW
Conhecendo o CorelDRAWConhecendo o CorelDRAW
Conhecendo o CorelDRAWMarcio Duarte
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillMario Heiderich
 
Devops, ça change quoi pour moi développeur ?
Devops, ça change quoi pour moi développeur ?Devops, ça change quoi pour moi développeur ?
Devops, ça change quoi pour moi développeur ?antony_guilloteau
 
Domain-Driven Design workshops
Domain-Driven Design workshopsDomain-Driven Design workshops
Domain-Driven Design workshopsMariusz Kopylec
 
Domain-Driven Design und Hexagonale Architektur
Domain-Driven Design und Hexagonale ArchitekturDomain-Driven Design und Hexagonale Architektur
Domain-Driven Design und Hexagonale ArchitekturTorben Fojuth
 
Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!cyrilpicat
 
Domain driven design
Domain driven designDomain driven design
Domain driven designjstack
 
EmpowerLA Elections Manual
EmpowerLA Elections ManualEmpowerLA Elections Manual
EmpowerLA Elections ManualEmpowerLA
 
EmpowerLA - Elections 2014 - Acceptable Forms
EmpowerLA - Elections 2014 - Acceptable FormsEmpowerLA - Elections 2014 - Acceptable Forms
EmpowerLA - Elections 2014 - Acceptable FormsEmpowerLA
 
EmpowerLA Elections - Candidate Guidelines
EmpowerLA Elections - Candidate GuidelinesEmpowerLA Elections - Candidate Guidelines
EmpowerLA Elections - Candidate GuidelinesEmpowerLA
 

Destaque (20)

Etapas de la vida
Etapas de la vidaEtapas de la vida
Etapas de la vida
 
EmpowerLA - Election 2014 - Timeline - Region 1
EmpowerLA - Election 2014 - Timeline - Region 1EmpowerLA - Election 2014 - Timeline - Region 1
EmpowerLA - Election 2014 - Timeline - Region 1
 
Informe gestión ambiental CDMC 2016
Informe gestión ambiental CDMC 2016Informe gestión ambiental CDMC 2016
Informe gestión ambiental CDMC 2016
 
Sistema Integrado de Gestión y Autocontrol
Sistema Integrado de Gestión y AutocontrolSistema Integrado de Gestión y Autocontrol
Sistema Integrado de Gestión y Autocontrol
 
Qualité de code, sonar, la dette
Qualité de code, sonar, la detteQualité de code, sonar, la dette
Qualité de code, sonar, la dette
 
Polígono e Padrões
Polígono e PadrõesPolígono e Padrões
Polígono e Padrões
 
Desenho técnico básico - Camiseta Regata
Desenho técnico básico - Camiseta RegataDesenho técnico básico - Camiseta Regata
Desenho técnico básico - Camiseta Regata
 
Conhecendo o CorelDRAW
Conhecendo o CorelDRAWConhecendo o CorelDRAW
Conhecendo o CorelDRAW
 
Desenhando Bolsos
Desenhando BolsosDesenhando Bolsos
Desenhando Bolsos
 
Vetorizando imagem
Vetorizando imagemVetorizando imagem
Vetorizando imagem
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the Sill
 
Devops, ça change quoi pour moi développeur ?
Devops, ça change quoi pour moi développeur ?Devops, ça change quoi pour moi développeur ?
Devops, ça change quoi pour moi développeur ?
 
Domain-Driven Design workshops
Domain-Driven Design workshopsDomain-Driven Design workshops
Domain-Driven Design workshops
 
Domain-Driven Design und Hexagonale Architektur
Domain-Driven Design und Hexagonale ArchitekturDomain-Driven Design und Hexagonale Architektur
Domain-Driven Design und Hexagonale Architektur
 
Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!
 
Domain driven design
Domain driven designDomain driven design
Domain driven design
 
What is DDD and how could it help you
What is DDD and how could it help youWhat is DDD and how could it help you
What is DDD and how could it help you
 
EmpowerLA Elections Manual
EmpowerLA Elections ManualEmpowerLA Elections Manual
EmpowerLA Elections Manual
 
EmpowerLA - Elections 2014 - Acceptable Forms
EmpowerLA - Elections 2014 - Acceptable FormsEmpowerLA - Elections 2014 - Acceptable Forms
EmpowerLA - Elections 2014 - Acceptable Forms
 
EmpowerLA Elections - Candidate Guidelines
EmpowerLA Elections - Candidate GuidelinesEmpowerLA Elections - Candidate Guidelines
EmpowerLA Elections - Candidate Guidelines
 

Semelhante a Php 100k

BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...
BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...
BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...Publicis Sapient Engineering
 
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014Benoît de CHATEAUVIEUX
 
Décryptage des LLMs au-delà de la hype - Lyon Data science
Décryptage des LLMs au-delà de la hype - Lyon Data scienceDécryptage des LLMs au-delà de la hype - Lyon Data science
Décryptage des LLMs au-delà de la hype - Lyon Data scienceMarie-Alice Blete
 
VDLT - Retour DevFest 2023
VDLT - Retour DevFest 2023VDLT - Retour DevFest 2023
VDLT - Retour DevFest 2023SpikeeLabs
 
2012 02-09-eranea-presentation-jug-lausanne
2012 02-09-eranea-presentation-jug-lausanne2012 02-09-eranea-presentation-jug-lausanne
2012 02-09-eranea-presentation-jug-lausanneDidier Durand
 
Un site web rapide ?
Un site web rapide ? Un site web rapide ?
Un site web rapide ? haricot
 
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?Drupagora 2013 : Drupal8 et Symfony2, quel impact ?
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?ekino
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPrestaShop
 
20131024 qualité de code et sonar - mug lyon
20131024   qualité de code et sonar - mug lyon20131024   qualité de code et sonar - mug lyon
20131024 qualité de code et sonar - mug lyonClement Bouillier
 
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...Microsoft
 
YLT paris js - mars 2015
YLT paris js - mars 2015YLT paris js - mars 2015
YLT paris js - mars 2015gaelmetais
 
Decouvrir CQRS (sans Event sourcing) par la pratique
Decouvrir CQRS (sans Event sourcing) par la pratiqueDecouvrir CQRS (sans Event sourcing) par la pratique
Decouvrir CQRS (sans Event sourcing) par la pratiqueThomas Pierrain
 
Php forum 2017 - Maisons du Monde
Php forum 2017 - Maisons du MondePhp forum 2017 - Maisons du Monde
Php forum 2017 - Maisons du Mondemarchugon
 
Réussir son projet Drupal
Réussir son projet DrupalRéussir son projet Drupal
Réussir son projet DrupalAdyax
 
Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Cellenza
 
Au cœur du Framework .NET 4.5.1
Au cœur du Framework .NET 4.5.1Au cœur du Framework .NET 4.5.1
Au cœur du Framework .NET 4.5.1Microsoft
 
StyleCop avec visual studio 2010
StyleCop avec visual studio 2010StyleCop avec visual studio 2010
StyleCop avec visual studio 2010Novencia Groupe
 

Semelhante a Php 100k (20)

BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...
BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...
BigData et Hadoop au secours de téraoctets de logs inexploitables chez l'un d...
 
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
 
Décryptage des LLMs au-delà de la hype - Lyon Data science
Décryptage des LLMs au-delà de la hype - Lyon Data scienceDécryptage des LLMs au-delà de la hype - Lyon Data science
Décryptage des LLMs au-delà de la hype - Lyon Data science
 
VDLT - Retour DevFest 2023
VDLT - Retour DevFest 2023VDLT - Retour DevFest 2023
VDLT - Retour DevFest 2023
 
Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015
 
_JCVFr
_JCVFr_JCVFr
_JCVFr
 
2012 02-09-eranea-presentation-jug-lausanne
2012 02-09-eranea-presentation-jug-lausanne2012 02-09-eranea-presentation-jug-lausanne
2012 02-09-eranea-presentation-jug-lausanne
 
Un site web rapide ?
Un site web rapide ? Un site web rapide ?
Un site web rapide ?
 
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?Drupagora 2013 : Drupal8 et Symfony2, quel impact ?
Drupagora 2013 : Drupal8 et Symfony2, quel impact ?
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShop
 
20131024 qualité de code et sonar - mug lyon
20131024   qualité de code et sonar - mug lyon20131024   qualité de code et sonar - mug lyon
20131024 qualité de code et sonar - mug lyon
 
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...
Eco Conception logicielle : Comment réduire par deux la consommation d&rsquo;...
 
YLT paris js - mars 2015
YLT paris js - mars 2015YLT paris js - mars 2015
YLT paris js - mars 2015
 
Decouvrir CQRS (sans Event sourcing) par la pratique
Decouvrir CQRS (sans Event sourcing) par la pratiqueDecouvrir CQRS (sans Event sourcing) par la pratique
Decouvrir CQRS (sans Event sourcing) par la pratique
 
Php forum 2017 - Maisons du Monde
Php forum 2017 - Maisons du MondePhp forum 2017 - Maisons du Monde
Php forum 2017 - Maisons du Monde
 
Réussir son projet Drupal
Réussir son projet DrupalRéussir son projet Drupal
Réussir son projet Drupal
 
Drupal & Mobilité
Drupal & MobilitéDrupal & Mobilité
Drupal & Mobilité
 
Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1
 
Au cœur du Framework .NET 4.5.1
Au cœur du Framework .NET 4.5.1Au cœur du Framework .NET 4.5.1
Au cœur du Framework .NET 4.5.1
 
StyleCop avec visual studio 2010
StyleCop avec visual studio 2010StyleCop avec visual studio 2010
StyleCop avec visual studio 2010
 

Mais de Francois Zaninotto

Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !Francois Zaninotto
 
La blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré luiLa blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré luiFrancois Zaninotto
 
Le jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du webLe jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du webFrancois Zaninotto
 
La programmation asynchrone... et les pates
La programmation asynchrone... et les patesLa programmation asynchrone... et les pates
La programmation asynchrone... et les patesFrancois Zaninotto
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfonyFrancois Zaninotto
 

Mais de Francois Zaninotto (10)

Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !
 
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
 
La blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré luiLa blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré lui
 
Le jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du webLe jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du web
 
La programmation asynchrone... et les pates
La programmation asynchrone... et les patesLa programmation asynchrone... et les pates
La programmation asynchrone... et les pates
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Ce bon vieux propel
Ce bon vieux propelCe bon vieux propel
Ce bon vieux propel
 
Symfony2 meets propel 1.5
Symfony2 meets propel 1.5Symfony2 meets propel 1.5
Symfony2 meets propel 1.5
 
Developing for Developers
Developing for DevelopersDeveloping for Developers
Developing for Developers
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 

Php 100k