90
Ca ressemble à quoi François Zaninotto - @francoisz Une application PHP, quand on arrive à 100 000 lignes de code marmelab - PHP Tour Lyon 2014

Php 100k

Embed Size (px)

DESCRIPTION

Vous ne manquez pas de tutoriels pour écrire un "Hello, world" avec n'importe quel framework. Mais que se passe-t-il quand, sur cette base, vous faites travailler une équipe de 4 développeurs pendant 6 mois ? Petit retour d'expérience sur l'architecture logicielle d'une application Symfony2 de taille moyenne, avec des visualisations inédites et des indices pour répondre à cette éternelle question : mais où je le mets ce code ? Présentation effectuée au PHP Tour Lyon 2014

Citation preview

Page 1: Php 100k

Ca ressemble à quoi

François Zaninotto - @francoisz

Une application PHP, quand on arrive à 100 000 lignes de code

marmelab - PHP Tour Lyon 2014

Page 2: Php 100k
Page 3: Php 100k

Ca ressemble à ç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.

Page 4: Php 100k

✦ 10 loc

✦ 100 loc

✦ 1 Kloc

✦ 10 Kloc

✦ 100 Kloc

✦ 1 Mloc

✦ 10 Mloc

Page 5: Php 100k

✦ 10 loc

✦ 100 loc

✦ 1 Kloc

✦ 10 Kloc

✦ 100 Kloc

✦ 1 Mloc

✦ 10 Mloc

« 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)

Page 6: Php 100k

✦ 10 loc

✦ 100 loc

✦ 1 Kloc

✦ 10 Kloc

✦ 100 Kloc

✦ 1 Mloc

✦ 10 Mloc

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)

Page 7: Php 100k

✦ 10 loc

✦ 100 loc

✦ 1 Kloc

✦ 10 Kloc

✦ 100 Kloc

✦ 1 Mloc

✦ 10 Mloc

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)

Page 8: Php 100k

✦ 10 loc

✦ 100 loc

✦ 1 Kloc

✦ 10 Kloc

✦ 100 Kloc

✦ 1 Mloc

✦ 10 Mloc

Etna

Page 9: Php 100k

Pourquoi c’est important• 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…

Page 10: Php 100k
Page 11: Php 100k

1- Se situer 2 - Découvrir

3 - Faire évoluer 4 - Entretenir

Page 12: Php 100k

1- Se situer

Page 13: Php 100k

Se situer : le problè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 tellement perdu que vous avez peur. • 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 se situer. • 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

Page 14: Php 100k

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/daterangeIpicker%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%.

Page 15: Php 100k

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.

Page 16: Php 100k

#%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

Page 17: Php 100k

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.

Page 18: Php 100k

Quelles sont les masses de code?

CodeFlower

Page 19: Php 100k

Où est le code, avec plus de dé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 Code Flower. • 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)

Page 20: Php 100k

%%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

Page 21: Php 100k

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!

Page 22: Php 100k

#%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%:

Page 23: Php 100k

Sur quelles librairies s’appuie le projet ?

DependencyWheel

Page 24: Php 100k

Et les dé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, ce n’est pas vous qui l’écrivez. Le gros du code est dans les dépendances. • Sur Etna, les dépendances représentent 90% du code 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?

Page 25: Php 100k

N’oubliez pas JS et CSS

Page 26: Php 100k

N’oubliez pas le JS et le CSS• 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

Page 27: Php 100k

✓ Se situer

Page 28: Php 100k

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 !

Page 29: Php 100k

2- Découvrir

Page 30: Php 100k

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 à mieux comprendre cette application à 100 000 lignes de code.

• Il commence à s’éloigner un peu 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.

• De classe en classe, 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.

Page 31: Php 100k

#%que%fait%cette%classe?%>%phpunit%Ic%app%—filter%ContentLocker%—testdox%!Etna\ArticleBundle\Service\ContentLocker%%[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

Page 32: Php 100k

Les tests unitaires• De manière peut-être inattendue, le premier guide à interroger, ce sont les tests

unitaires.

• Les tests décrivent ce qu’une classe doit faire. Ils décrivent aussi ce qu’une classe n’arrive plus à faire quand on la casse. Ils sont donc forcément présent dans une application à 100 000 lignes de code (sinon elle n’est pas maintenable).

• 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)

Page 33: Php 100k

<?php%class%ContentLockerTest%extends%\PHPUnit_Framework_TestCase%{%%%%%public%function%testLockContentShouldPersistALock()%%%%%{%%%%%%%%%//%...%%%%%}%!%%%%public%function%testLockContentShouldBeSetWithCorrectDataWhenPersisted()%%%%%{%%%%%%%%%//%...%%%%%}%!%%%%public%function%testLockContentShouldNotBePersistedIfAlreadyExists()%%%%%{%%%%%%%%%//%...%%%%%}%}

Page 34: Php 100k

Les tests unitaires

• 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 ?

Page 35: Php 100k

Et la doc?

Page 36: Php 100k

La Doc• 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 : la documentation, c’est le code (« 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 lu par 2 choses : 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.

Page 37: Php 100k

Sans commentaire

Page 38: Php 100k

Les commentaires• 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 phpDoc paraphrase, 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 quand le code ne dit pas tout, 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 ligne de commentaire pour 20 lignes de code. C’est qu’un code bien écrit est son propre commentaire. Un code bien écrit est sa propre documentation.

Page 39: Php 100k

%%%%/**%%%%%%*%Returns%the%price%%%%%%*%%%%%%*%@param%TaxRule%$tax%The%tax%rule%%%%%%*/%%%%%public%function%getPrice(TaxRule%$tax)%%%%%{%%%%%%%%%//%...%%%%%}%

Page 40: Php 100k

Et la Doc API ?

Page 41: Php 100k

Faire le point, dresser l’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 inventaire physique. Ce qu’il faut pour découvrir l’application, c’est un inventaire logique, un inventaire des classes et des méthodes.

• Cette liste, on appelle ça la Doc API. 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.

Page 42: Php 100k

Que fait cette classe ?

Sami

Page 43: Php 100k

Read the source, 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 justement pour qu’il soit lisible par un humain.

• 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.

Page 44: Php 100k

De quoi dépend un composant ?

ArchitectureTree

Page 45: Php 100k

Représenter l’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éma d’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 !

Page 46: Php 100k

{%"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"]%}%%%]%}

Page 47: Php 100k

Architecture Tree : la source

• 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.

Page 48: Php 100k

✓ Découvrir

Page 49: Php 100k

Conclusion• Avouez que cette application de 100 000 lignes de code, elle ne vous fait dé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, à donner envie au développeur.

• Incidemment, ces outils permettent de découvrir des choses qu’on ne cherchait pas. 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.

Page 50: Php 100k

3 - Faire évoluer

Page 51: Php 100k

3 - Faire évoluer• L’aventure, c’est de faire évoluer cette application de 100 000 lignes de code.

• C’est ce qu’on vous demande tous les jours. « 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 davantage de lignes de code. 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.

• Comment implémenter une nouvelle fonctionnalité ? 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 trouver le bon chemin 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.

Page 52: Php 100k

Design Patterns

Page 53: Php 100k

Design Patterns• 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.

Page 54: Php 100k
Page 55: Php 100k

Full stack Framework

Page 56: Php 100k

Utiliser un Framework full-stack• D’ailleurs, plutôt que d’essayer d’implémenter le pattern MVC tout seul, il vaut mieux

utiliser un framework 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.

Page 57: Php 100k

Bonnes pratiques

Page 58: Php 100k

Bonnes pratiques• 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.

Page 59: Php 100k

>%ls%src/Etna%!

AdminBundle%%%%%%%%%%%OriginBundle%ArticleBundle%%%%%%%%%SurveyBundle%FrameworkBundle%%%%%%%TagBundle%FrontUserBundle%%%%%%%TrackingBundle%HpeBundle%%%%%%%%%%%%%UserBundle%MiscBundle%%%%%%%%%%%%VideoBundle%NotificationBundle

Page 60: Php 100k

>%ls%src/Etna%!

Article%%%%%%%%%%%%%%%Survey%EtnaBundle%%%%%%%%%%%%Tag%FrontUser%%%%%%%%%%%%%Tracking%HPE%%%%%%%%%%%%%%%%%%%User%Notification%%%%%%%%%%Video%Origin%

Page 61: Php 100k

Le bon nom

Page 62: Php 100k

There are only two hard things in Computer Science:

cache invalidation and naming things.

!

Phil Karlton

Page 63: Php 100k

Le bon nom• 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.

Page 64: Php 100k

ArticleManager%TagTools%TrackingUtils%NotificationService

Page 65: Php 100k

Entities%% % % % Services%Article%% % % % % ContentLocker%Notification%% % ArticleCleaner%Lock% % % % % % % SurveyParser%TagRepository%% % UrlGenerator%Link% % % % % % % LiveImporter%!

Framework%classes%I%almost%empty%MediaFormType%LegacyIdListener%CleanContentCommand%ProfileAdminController%BreadcrumbTwigExtension

Page 66: Php 100k

Définir des Standards de nommage• 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.

Page 67: Php 100k

Respecter les standards

Page 68: Php 100k

#!/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% %!

Page 69: Php 100k

Standard de codage• Un projet de 100 000 lignes de code, c’est au moins 4 développeurs pendant 6 mois. Ca

fait donc pas mal de monde qui passe sur l’appli

• Si chacun a sa propre manière de coder, ça devient très vite un beau sac de noeuds.

• A ce niveau, on ne peut pas se passer de standard de codage

• 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.

Page 70: Php 100k

✓ Faire évoluer

Page 71: Php 100k

Conclusion• Plus la base de code est grosse, plus il faut des rè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 à toutes les autres applis PHP de 100 000 lignes de code.

• 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’est la première fois.

• 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.

Page 72: Php 100k

4- Entretenir

Page 73: Php 100k

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.

Page 74: Php 100k

La dette technique

Page 75: Php 100k

La dette technique• 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.

Page 76: Php 100k

Quels sont les points faibles? SensioLabsInsight

Page 77: Php 100k

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 !

Page 78: Php 100k

Par où commencer ? ViolationSunburst

Page 79: Php 100k

Visualiser la dette technique• Sur un gros projet, la dette technique s’élève souvent à plusieurs mois. Un outil de

contrôle qualité comme Insight révèle facilement plusieurs centaines 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 la dette technique de ce fichier. 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 la couleur pour représenter la sévérité des violations comprises dans un répertoire. Plus c’est rouge, plus c’est critique.

Page 80: Php 100k

Ne pas oublier

Page 81: Php 100k

La dimension temporelle• 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.

Page 82: Php 100k

Qu’est-ce qui peut casser?

ArcheoloGit

Page 83: Php 100k

✓ Entretenir

Page 84: Php 100k

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é

Page 85: Php 100k

Conclusion

Page 86: Php 100k

1 Million LOC

Page 87: Php 100k

Conclusion finale• A quoi ça ressemble une appli de 100 000 ligne de code ? Ca dépend de quel côté on regarde.

• J’espère vous avoir donné des outils et des visualisations 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 changer point de vue de temps à autre, de prendre de la hauteur pour mieux distinguer les lignes de force.

• Entretenir une telle application, c’est un travail d’équipe. Partagez vos visualisations avec toute l’équipe de développement pour qu’ils les fassent vivre. Cultivez la propriété collective du code 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 ?

Page 88: Php 100k

Microservices

Page 89: Php 100k

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.

Page 90: Php 100k

MerciCloc 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çois Zaninotto - @francoisz