From bd31267ff4450efb1462ce8193c4fb1135df4a66 Mon Sep 17 00:00:00 2001 From: Fred Pauchet Date: Thu, 24 Mar 2022 18:56:29 +0100 Subject: [PATCH] Switching to LaTeX --- .gitignore | 1 + sources/Dockerfile => Dockerfile | 0 book/contributors.adoc | 0 .../chapters => chapters}/architecture.tex | 0 .../chapters => chapters}/introduction.tex | 48 +- {sources/chapters => chapters}/licence.tex | 0 chapters/maintenability.tex | 136 ++++ .../programming-poetry.tex | 0 {sources/chapters => chapters}/thanks.tex | 0 docker-miktex.sh | 5 +- sources/main.tex => main.tex | 6 +- {sources/parts => parts}/environment.tex | 0 sources/references.bib => references.bib | 0 source/main.tex | 650 ------------------ sources/chapters/maintenability.tex | 61 -- 15 files changed, 163 insertions(+), 744 deletions(-) rename sources/Dockerfile => Dockerfile (100%) delete mode 100644 book/contributors.adoc rename {sources/chapters => chapters}/architecture.tex (100%) rename {sources/chapters => chapters}/introduction.tex (78%) rename {sources/chapters => chapters}/licence.tex (100%) create mode 100644 chapters/maintenability.tex rename {sources/chapters => chapters}/programming-poetry.tex (100%) rename {sources/chapters => chapters}/thanks.tex (100%) rename sources/main.tex => main.tex (96%) rename {sources/parts => parts}/environment.tex (100%) rename sources/references.bib => references.bib (100%) delete mode 100644 sources/chapters/maintenability.tex diff --git a/.gitignore b/.gitignore index 82b703a..7f34416 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ build *.log *.vscode/ *.asciidoctor/ +*.aux diff --git a/sources/Dockerfile b/Dockerfile similarity index 100% rename from sources/Dockerfile rename to Dockerfile diff --git a/book/contributors.adoc b/book/contributors.adoc deleted file mode 100644 index e69de29..0000000 diff --git a/sources/chapters/architecture.tex b/chapters/architecture.tex similarity index 100% rename from sources/chapters/architecture.tex rename to chapters/architecture.tex diff --git a/sources/chapters/introduction.tex b/chapters/introduction.tex similarity index 78% rename from sources/chapters/introduction.tex rename to chapters/introduction.tex index 80a0378..79923d0 100644 --- a/sources/chapters/introduction.tex +++ b/chapters/introduction.tex @@ -6,24 +6,25 @@ The only way to go fast, is to go well --- Robert C. Martin \end{quote} -Nous n'allons pas vous mentir: il existe enormément de tutoriaux très +Nous n'allons pas vous mentir: il existe énormément de tutoriaux très bien réalisés sur "\emph{Comment réaliser une application Django}" et autres "\emph{Déployer votre code en 2 minutes}". Nous nous disions juste que ces tutoriaux restaient relativement haut-niveaux et se limitaient à un contexte donné, sans réellement préparer à la maintenance et au suivi de l'application nouvellement développée. -L'idée du texte ci-dessous est de jeter les bases d'un bon -développement, en survolant l'ensemble des outils permettant de suivre -des lignes directrices reconnues, de maintenir une bonne qualité de code -au travers des différentes étapes menant jusqu'au déploiement et de -s'assurer du maintient correct de la base de code, en permettant à -n'importe qui de reprendre ce qui aura déjà été écrit. +Les quelques idées ci-dessous de jeter les bases d'un bon développement, en -Ces idées ne s'appliquent pas uniquement à Django et à son cadre de -travail, ni même au langage Python. Ces deux sujets sont cependant de -bons candidats et leur cadre de travail est bien défini, documenté et -suffisamment flexible. +\begin{itemize} + \item Survolant l'ensemble des lignes directrices reconnues + \item Maintenant une bonne qualité de code + \item Parcourant les différentes étapes du développement qui mèneront jusqu'au déploiement + \item Maintenant correctement la base de données + \item Permettant à quiconque de reprendre ce qui aura déjà été écrit. +\end{itemize} + +Ces idées ne s'appliquent pas uniquement à Django et à son cadre de travail, ni même au langage Python en particulier. +Ces deux sujets sont cependant de bons candidats et leur utilisation et cadre de travail sont bien définis, documentés et flexibles. Django se présente comme un \emph{Framework Web pour perfectionnistes ayant des deadlines} \cite{django} et suit ces quelques principes @@ -31,34 +32,25 @@ ayant des deadlines} \cite{django} et suit ces quelques principes \begin{itemize} \item - Faible couplage et forte cohésion, pour que chaque composant dispose - de son indépendance, en n'ayant aucune connaissance des autres couches - applicatives. Ainsi, le moteur de rendu ne connait absolument rien - l'existence du moteur de base de données, tout comme le système de - vues ne sait pas quel moteur de rendu est utilisé. + \textbf{Faible couplage et forte cohésion}, pour que chaque composant dispose de son indépendance, en n'ayant aucune connaissance des autres couches applicatives. Ainsi, le moteur de rendu ne connait absolument rien à l'existence du moteur de base de données, tout comme le système de vues ne sait pas quel moteur de rendu est utilisé. \item - Plus de fonctionnalités avec moins de code: chaque application Django + \textbf{Plus de fonctionnalités avec moins de code}: chaque application Django doit utiliser le moins de code possible \item - \emph{Don't repeat yourself}, chaque concept ou morceau de code ne + \textbf{\emph{Don't repeat yourself}}, chaque concept ou morceau de code ne doit être présent qu'à un et un seul endroit de vos dépôts. \item - Rapidité du développement, en masquant les aspects fastidieux du + \textbf{Rapidité du développement}, en masquant les aspects fastidieux du développement web actuel \end{itemize} Mis côte à côte, le suivi de ces principes permet une bonne stabilité du projet à moyen et long terme. -Comme nous le verrons par la suite, et sans être parfait, Django offre -une énorme flexibilité qui permet de se laisser le maximum d'options -ouvertes tout en permettant d'expérimenter facilement plusieurs pistes, -jusqu'au moment de prendre une vraie décision. Dans la majorité des cas -problématiques pouvant être rencontrés lors du développement d'une -application Web, Django proposera une solution pragmatique, -compréhensible et facile à mettre en place. En résumé de ce paragraphe, -pour tout problème commun, vous disposerez d'une solution logique. Tout -pour plaire à n'importe quel directeur IT. +Sans être parfait, Django offre une énorme flexibilité qui permet de conserver un maximum d'options ouvertes et de facilement expérimenter différentes pistes, jusqu'au moment de prendre une vraie décision. +Pour la (grande) majorité des problèmes rencontrés lors du développement d'une application Web, Django proposera une solution pragmatique, compréhensible et facile à mettre en place: pour tout problème communément connu, vous disposerez d'une solution logique. + +Tout pour plaire à n'importe quel directeur IT. \textbf{Dans la première partie}, nous verrons comment partir d'un environnement sain, comment le configurer correctement, comment diff --git a/sources/chapters/licence.tex b/chapters/licence.tex similarity index 100% rename from sources/chapters/licence.tex rename to chapters/licence.tex diff --git a/chapters/maintenability.tex b/chapters/maintenability.tex new file mode 100644 index 0000000..6234aeb --- /dev/null +++ b/chapters/maintenability.tex @@ -0,0 +1,136 @@ +\chapter{Fiabilité, évolutivité et maintenabilité} + +\begin{quote} +The primary cost of maintenance is in spelunking and risk + \cite[139]{clean_architecture} + +--- Robert C. Martin +\end{quote} + +\section{Poésie de la programmation} + +\begin{quote} +La poésie est "l'art d'évoquer et de suggérer les sensations, les impressions, les émotions les plus vives par l'union intense des sons, des rythmes, des harmonies, en particulier par les vers." + +-- https://www.larousse.fr/dictionnaires/francais/po%C3%A9sie/61960 +\end{quote} + +Sans aller jusqu'à demander de développer vos algorithmes sur douze pieds, la programmation reste un art régit par un ensemble de bonnes pratiques, par des règles à respecter et par la nécessité de travailler avec d'autres personnes qui ont \sout{parfois} souvent une expérience, des compétences ou une approche différente. + +\section{Tests unitaires et d'intégration} + +\begin{quote} +Tests are part of the system. +You can think of tests as the outermost circle in the architecture. +Nothing within in the system depends on the tests, and the tests always depend inward on the components of the system. + +-- Robert C. Martin, Clean Architecture +\end{quote} + +\section{Complexité cyclomatique\index{McCabe}} + +La \href{https://fr.wikipedia.org/wiki/Nombre_cyclomatique}{complexité cyclomatique} (ou complexité de McCabe) peut s'apparenter à mesure de difficulté de compréhension du code, en fonction du nombre d'embranchements trouvés dans une même section. +Quand le cycle d'exécution du code rencontre une condition, cette condition peut être évalue à VRAI ou à FAUX. +L'exécution du code dispose donc de deux embranchements, correspondant chacun à un résultat de cette condition. + +Le code suivant \autoref{cyclomatic-simple-code} a une complexité cyclomatique 1; il s'agit du cas le plus simple que nous pouvons implémenter: l'exécution du code rentre dans la fonction (il y a un seul embranchement), et aucun bloc conditionnel n'est présent sur son chemin. +La complexité reste de 1. + +\begin{listing}[!hbpt] + \begin{minted}{Python} + from datetime import date + + def print_current_date(): + print(date.today()) + \end{minted} + \caption{Une version ultra-simple de l'affichage du jour de la semaine} + \label{cyclomatic-simple-code} +\end{listing} + +Si nous complexifions cette fonction en vérifiant (par exemple) le jour de la semaine, nous aurons notre embranchement initial (l'impression à l'écran de la date du jour), mais également un second embranchement qui vérifiera si cette date correspond à un lundi: + +\begin{listing}[!h] + \begin{minted}{Python} + from datetime import date + + def print_current_date_if_monday(): + if date.today().weekday() == 0: + print("Aujourd'hui, c'est lundi!") + print(date.today()) + \end{minted} + \caption{Ajout d'une fonctionnalité essentielle et totalement indispensable} +\end{listing} + +La complexité cyclomatique d'un bloc est évaluée sur base du nombre d'embranchements possibles; par défaut, sa valeur est de 1. +Si nous rencontrons une condition, elle passera à 2, etc. +Cette complexité est liée à deux concepts: + +\begin{itemize} + \item \textbf{La lisibilité du code}: au plus la complexité cyclomatique sera élevée, au plus le code sera compliqué à comprendre en première instance. Il sera composé de plusieurs conditions, éventuellement imbriquées, il débordera probablement de la hauteur que votre écran sera capable d'afficher + \item \textbf{Les tests unitaires}: pour nous assurer d'une couverture de code correcte, il sera nécessaire de couvrir tous les embranchements présentés. Connaître la complexité permet de savoir combien de tests devront être écrits pour assurer une couverture complète de tous les cas pouvant se présenter. +\end{itemize} + +\subsection{Lisibilité du code} + +Il est important de noter que refactoriser un bloc, par exemple en extrayant une méthode, n'améliore pas la complexité cyclomatique globale de l'application. +L'amélioration que nous visons ici est une amélioration \textbf{locale}, qui facilite la lecture d'un bloc spécifique, et pas d'un programme complet. + +"Améliorons" notre code ci-dessous, pour lui ajouter la possibilité de gérer les autres jours de la semaine: + +\begin{listing}[!ht] + \begin{minted}{Python} + from datetime import date + + def print_current_date(): + if date.today().weekday() == 0: + print("Lundi") + elif date.today().weekday() == 1: + print("Mardi") + elif date.today().weekday() == 2: + print("Mercredi") + elif date.today().weekday() == 3: + print("Jeudi") + elif date.today().weekday() == 4: + print("Vendredi") + elif date.today().weekday() == 5: + print("Samedi") + elif date.today().weekday() == 6: + print("Dimanche") + print(date.today()) + \end{minted} + \caption{Un code un peu nul avec une complexité cyclomatique qui l'est tout autant} + \label{Impression du jour de la semaine, version naïve} +\end{listing} + +La complexité de ce code est évaluée à 8, même si la complexité effective ne sera que de 7. +Extraire une méthode à partir de ce bloc pourra réduire la complexité de la fonction \mintinline{python}{print_current_date} n'améliorera rien et ne fera que déplacer le problème. +Une solution serait de passer par un dictionnaire, de façon à ramener la complexité à 1: + +\begin{listing}[!ht] + \begin{minted}{python} + from datetime import date + + def print_current_date(): + DAYS_OF_WEEK = { + 0: "Lundi", + 1: "Mardi", + 2: "Mercredi", + 3: "Jeudi", + 4: "Vendredi", + 5: "Samedi", + 6: "Dimanche" + } + + print(DAYS_OF_WEEK.get(date.today().weekday())) + print(date.today()) + \end{minted} + \caption{La même version, avec une complexité réduite à 1} +\end{listing} + + +\subsection{Tests unitaires} + +Le nombre de tests unitaires nécessaires à la couverture d'un bloc fonctionnel est au minimum égal à la complexité cyclomatique de ce bloc. +Une possibilité pour améliorer la maintenance du code est de faire baisser ce nombre, et de le conserver sous un certain seuil. +Certains recommandent de le garder sous une complexité de 10; d'autres de 5. + diff --git a/sources/chapters/programming-poetry.tex b/chapters/programming-poetry.tex similarity index 100% rename from sources/chapters/programming-poetry.tex rename to chapters/programming-poetry.tex diff --git a/sources/chapters/thanks.tex b/chapters/thanks.tex similarity index 100% rename from sources/chapters/thanks.tex rename to chapters/thanks.tex diff --git a/docker-miktex.sh b/docker-miktex.sh index 59ad566..e3b3a63 100755 --- a/docker-miktex.sh +++ b/docker-miktex.sh @@ -1,2 +1,5 @@ -docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex/miktex pdflatex sources/main.tex +docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments pdflatex main.tex -shell-escape +docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments makeindex main.idx +docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments bibtex main +docker run -ti -v miktex:/miktex/.miktex -v `pwd`:/miktex/work miktex-pygments pdflatex main.tex -shell-escape diff --git a/sources/main.tex b/main.tex similarity index 96% rename from sources/main.tex rename to main.tex index 149fb64..bdad46c 100644 --- a/sources/main.tex +++ b/main.tex @@ -6,6 +6,7 @@ \usepackage{setspace} \usepackage{listing} \usepackage{minted} +\usepackage{ulem} \onehalfspacing @@ -29,13 +30,12 @@ \tableofcontents \listoffigures \listoftables +\listoflistings \mainmatter \include{parts/environment.tex} -\include{chapters/programming-poetry.tex} - \include{chapters/maintenability.tex} \include{chapters/architecture.tex} @@ -107,8 +107,6 @@ \chapter{Khana} -\chapter{Tests unitaires} - \chapter{Refactoring} \chapter{Conclusions} diff --git a/sources/parts/environment.tex b/parts/environment.tex similarity index 100% rename from sources/parts/environment.tex rename to parts/environment.tex diff --git a/sources/references.bib b/references.bib similarity index 100% rename from sources/references.bib rename to references.bib diff --git a/source/main.tex b/source/main.tex index 2ef1995..177782b 100644 --- a/source/main.tex +++ b/source/main.tex @@ -1,433 +1,4 @@ -% Options for packages loaded elsewhere -\PassOptionsToPackage{unicode}{hyperref} -\PassOptionsToPackage{hyphens}{url} -% -\documentclass[ -]{article} -\usepackage{lmodern} -\usepackage{amssymb,amsmath} -\usepackage{ifxetex,ifluatex} -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[T1]{fontenc} - \usepackage[utf8]{inputenc} - \usepackage{textcomp} % provide euro and other symbols -\else % if luatex or xetex - \usepackage{unicode-math} - \defaultfontfeatures{Scale=MatchLowercase} - \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} -\fi -% Use upquote if available, for straight quotes in verbatim environments -\IfFileExists{upquote.sty}{\usepackage{upquote}}{} -\IfFileExists{microtype.sty}{% use microtype if available - \usepackage[]{microtype} - \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts -}{} -\makeatletter -\@ifundefined{KOMAClassName}{% if non-KOMA class - \IfFileExists{parskip.sty}{% - \usepackage{parskip} - }{% else - \setlength{\parindent}{0pt} - \setlength{\parskip}{6pt plus 2pt minus 1pt}} -}{% if KOMA class - \KOMAoptions{parskip=half}} -\makeatother -\usepackage{xcolor} -\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available -\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} -\hypersetup{ - pdftitle={Minor swing with Django}, - pdfauthor={Cédric Declerfayt jaguarondi27@gmail.com; Fred Pauchet fred@grimbox.be}, - hidelinks, - pdfcreator={LaTeX via pandoc}} -\urlstyle{same} % disable monospaced font for URLs -\usepackage{color} -\usepackage{fancyvrb} -\newcommand{\VerbBar}{|} -\newcommand{\VERB}{\Verb[commandchars=\\\{\}]} -\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} -% Add ',fontsize=\small' for more characters per line -\newenvironment{Shaded}{}{} -\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} -\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} -\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}} -\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} -\newcommand{\BuiltInTok}[1]{#1} -\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} -\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}} -\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} -\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}} -\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} -\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}} -\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} -\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}} -\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} -\newcommand{\ExtensionTok}[1]{#1} -\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} -\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}} -\newcommand{\ImportTok}[1]{#1} -\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} -\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} -\newcommand{\NormalTok}[1]{#1} -\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} -\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}} -\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}} -\newcommand{\RegionMarkerTok}[1]{#1} -\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} -\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}} -\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} -\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} -\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} -\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} -\usepackage{graphicx} -\makeatletter -\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} -\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} -\makeatother -% Scale images if necessary, so that they will not overflow the page -% margins by default, and it is still possible to overwrite the defaults -% using explicit options in \includegraphics[width, height, ...]{} -\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} -% Set default figure placement to htbp -\makeatletter -\def\fps@figure{htbp} -\makeatother -\setlength{\emergencystretch}{3em} % prevent overfull lines -\providecommand{\tightlist}{% - \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -\setcounter{secnumdepth}{-\maxdimen} % remove section numbering -\title{Minor swing with Django} -\author{Cédric Declerfayt -\href{mailto:jaguarondi27@gmail.com}{\nolinkurl{jaguarondi27@gmail.com}} \and Fred -Pauchet \href{mailto:fred@grimbox.be}{\nolinkurl{fred@grimbox.be}}} -\date{2022-02-20} - -\begin{document} -\maketitle - -\hypertarget{_licence}{% -\section{Licence}\label{_licence}} - -Ce travail est licencié sous Attribution-NonCommercial 4.0 International -Attribution-NonCommercial 4.0 International - -This license requires that reusers give credit to the creator. It allows -reusers to distribute, remix, adapt, and build upon the material in any -medium or format, for noncommercial purposes only. - -\begin{itemize} -\item - \textbf{BY}: Credit must be given to you, the creator. -\item - \textbf{NC}: Only noncommercial use of your work is permitted. - Noncommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. -\end{itemize} - -\url{https://creativecommons.org/licenses/by-nc/4.0/?ref=chooser-v1} - -La seule exception concerne les morceaux de code (non attribués), -disponibles sous licence \href{https://mit-license.org/}{MIT}. - -\hypertarget{_pruxe9face}{% -\section{Préface}\label{_pruxe9face}} - -\begin{quote} -The only way to go fast, is to go well - ---- Robert C. Martin -\end{quote} - -Nous n'allons pas vous mentir: il existe enormément de tutoriaux très -bien réalisés sur "\emph{Comment réaliser une application Django}" et -autres "\emph{Déployer votre code en 2 minutes}". Nous nous disions -juste que ces tutoriaux restaient relativement haut-niveaux et se -limitaient à un contexte donné, sans réellement préparer à la -maintenance et au suivi de l'application nouvellement développée. - -L'idée du texte ci-dessous est de jeter les bases d'un bon -développement, en survolant l'ensemble des outils permettant de suivre -des lignes directrices reconnues, de maintenir une bonne qualité de code -au travers des différentes étapes menant jusqu'au déploiement et de -s'assurer du maintient correct de la base de code, en permettant à -n'importe qui de reprendre ce qui aura déjà été écrit. - -Ces idées ne s'appliquent pas uniquement à Django et à son cadre de -travail, ni même au langage Python. Ces deux sujets sont cependant de -bons candidats et leur cadre de travail est bien défini, documenté et -suffisamment flexible. - -Django se présente comme un \emph{Framework Web pour perfectionnistes -ayant des deadlines} cite:{[}django{]} et suit ces quelques principes -cite:{[}django\_design\_philosophies{]}: - -\begin{itemize} -\item - Faible couplage et forte cohésion, pour que chaque composant dispose - de son indépendance, en n'ayant aucune connaissance des autres couches - applicatives. Ainsi, le moteur de rendu ne connait absolument rien - l'existence du moteur de base de données, tout comme le système de - vues ne sait pas quel moteur de rendu est utilisé. -\item - Plus de fonctionnalités avec moins de code: chaque application Django - doit utiliser le moins de code possible -\item - \emph{Don't repeat yourself}, chaque concept ou morceau de code ne - doit être présent qu'à un et un seul endroit de vos dépôts. -\item - Rapidité du développement, en masquant les aspects fastidieux du - développement web actuel -\end{itemize} - -Mis côte à côte, le suivi de ces principes permet une bonne stabilité du -projet à moyen et long terme. - -Comme nous le verrons par la suite, et sans être parfait, Django offre -une énorme flexibilité qui permet de se laisser le maximum d'options -ouvertes tout en permettant d'expérimenter facilement plusieurs pistes, -jusqu'au moment de prendre une vraie décision. Dans la majorité des cas -problématiques pouvant être rencontrés lors du développement d'une -application Web, Django proposera une solution pragmatique, -compréhensible et facile à mettre en place. En résumé de ce paragraphe, -pour tout problème commun, vous disposerez d'une solution logique. Tout -pour plaire à n'importe quel directeur IT. - -\textbf{Dans la première partie}, nous verrons comment partir d'un -environnement sain, comment le configurer correctement, comment -installer Django de manière isolée et comment démarrer un nouveau -projet. Nous verrons rapidement comment gérer les dépendances, les -versions et comment appliquer et suivre un score de qualité de notre -code. Ces quelques points pourront être appliqués pour n'importe quel -langage ou cadre de travail. Nous verrons aussi que la configuration -proposée par défaut par le framework n'est pas idéale dans la majorité -des cas. - -Pour cela, nous présenterons différents outils, la rédaction de tests -unitaires et d'intégration pour limiter les régressions, les règles de -nomenclature et de contrôle du contenu, comment partir d'un squelette -plus complet, ainsi que les bonnes étapes à suivre pour arriver à un -déploiement rapide et fonctionnel avec peu d'efforts. - -A la fin de cette partie, vous disposerez d'un code propre et d'un -projet fonctionnel, bien qu'encore un peu inutile. - -\textbf{Dans la deuxième partie}, nous aborderons les grands principes -de modélisation, en suivant les lignes de conduites du cadre de travail. -Nous aborderons les concepts clés qui permettent à une application de -rester maintenable, les formulaires, leurs validations, comment gérer -les données en entrée, les migrations de données et l'administration. - -\textbf{Dans la troisième partie}, nous détaillerons précisément les -étapes de déploiement, avec la description et la configuration de -l'infrastructure, des exemples concrets de mise à disposition sur deux -distributions principales (Debian et CentOS), sur une \emph{*Plateform -as a Service*}, ainsi que l'utilisation de Docker et Docker-Compose. - -Nous aborderons également la supervision et la mise à jour d'une -application existante, en respectant les bonnes pratiques -d'administration système. - -\textbf{Dans la quatrième partie}, nous aborderons les architectures -typées \emph{entreprise}, les services et les différentes manières de -structurer notre application pour faciliter sa gestion et sa -maintenance, tout en décrivant différents types de scénarii, en fonction -des consommateurs de données. - -\textbf{Dans la cinquième partie}, nous mettrons ces concepts en -pratique en présentant le développement en pratique de deux -applications, avec la description de problèmes rencontrés et la solution -qui a été choisie: définition des tables, gestion des utilisateurs, -\ldots\hspace{0pt} et mise à disposition. - -\hypertarget{_pour_qui}{% -\subsection{Pour qui ?}\label{_pour_qui}} - -Avant tout, pour moi. Comme le disait le Pr Richard Feynman: "\emph{Si -vous ne savez pas expliquer quelque chose simplement, c'est que vous ne -l'avez pas compris}". \footnote{Et comme l'ajoutait Aurélie Jean dans de - L'autre côté de la machine: \emph{"Si personne ne vous pose de - questions suite à votre explication, c'est que vous n'avez pas été - suffisamment clair !"} cite:{[}other\_side}{]} - -Ce livre s'adresse autant au néophyte qui souhaite se lancer dans le -développement Web qu'à l'artisan qui a besoin d'un aide-mémoire et qui -ne se rappelle plus toujours du bon ordre des paramètres, ou à l'expert -qui souhaiterait avoir un aperçu d'une autre technologie que son domaine -privilégié de compétences. - -Beaucoup de concepts présentés peuvent être oubliés ou restés inconnus -jusqu'au moment où ils seront réellement nécessaires. A ce moment-là, -pour peu que votre mémoire ait déjà entraperçu le terme, il vous sera -plus facile d'y revenir et de l'appliquer. - -\hypertarget{_pour_aller_plus_loin}{% -\subsection{Pour aller plus loin}\label{_pour_aller_plus_loin}} - -Il existe énormément de ressources, autant spécifiques à Django que plus -généralistes. Il ne sera pas possible de toutes les détailler; faites un -tour sur - -\begin{itemize} -\item - \url{https://duckduckgo.com}, -\item - \url{https://stackoverflow.com}, -\item - \url{https://ycombinator.com}, -\item - \url{https://lobste.rs/}, -\item - \url{https://lecourrierduhacker.com/} -\item - ou \url{https://www.djangoproject.com/}. -\end{itemize} - -Restez curieux, ne vous enclavez pas dans une technologie en particulier -et gardez une bonne ouverture d'esprit. - -\hypertarget{_conventions}{% -\subsection{Conventions}\label{_conventions}} - -Les notes indiquent des anecdotes. - -Les conseils indiquent des éléments utiles, mais pas spécialement -indispensables. - -Les notes importantes indiquent des éléments à retenir. - -Ces éléments indiquent des points d'attention. Les retenir vous fera -gagner du temps en débuggage. - -Les avertissements indiquent un (potentiel) danger ou des éléments -pouvant amener des conséquences pas spécialement sympathiques. - -Les morceaux de code source seront présentés de la manière suivante: - -\begin{Shaded} -\begin{Highlighting}[] -\CommentTok{\# \textless{}folder\textgreater{}/\textless{}fichier\textgreater{}.\textless{}extension\textgreater{} } - -\KeywordTok{def}\NormalTok{ function(param):} - \CommentTok{""" } -\CommentTok{ """} -\NormalTok{ callback() } -\end{Highlighting} -\end{Shaded} - -\begin{itemize} -\item - L'emplacement du fichier ou du morceau de code présenté, sous forme de - commentaire -\item - Des commentaires, si cela s'avère nécessaire -\item - Les parties importantes ou récemment modifiées seront surlignées. -\end{itemize} - -La plupart des commandes qui seront présentées dans ce livre le seront -depuis un shell sous GNU/Linux. Certaines d'entre elles pourraient -devoir être adaptées si vous utilisez un autre système d'exploitation -(macOS) ou n'importe quelle autre grosse bouse commerciale. - -\begin{quote} -Make it work, make it right, make it fast - ---- Kent Beck -\end{quote} - -En fonction de vos connaissances et compétences, la création d'une -nouvelle application est uneé tape relativement facile à mettre en -place. Le code qui permet de faire tourner cette application peut ne pas -être élégant, voire buggé jusqu'à la moëlle, il pourra fonctionner et -faire "preuve de concept". - -Les problèmes arriveront lorsqu'une nouvelle demande sera introduite, -lorsqu'un bug sera découvert et devra être corrigé ou lorsqu'une -dépendance cessera de fonctionner ou d'être disponible. Or, une -application qui n'évolue pas, meurt. Tout application est donc destinée, -soit à être modifiée, corrigée et suivie, soit à déperrir et à être -délaissée par ses utilisateurs. Et c'est juste cette maintenance qui est -difficile. - -L'application des principes présentés et agrégés ci-dessous permet -surtout de préparer correctement tout ce qui pourra arriver, sans aller -jusqu'au « \textbf{You Ain't Gonna Need It} » (ou \textbf{YAGNI}), qui -consiste à surcharger tout développement avec des fonctionnalités non -demandées, juste « au cas ou ». Pour paraphraser une partie de -l'introduction du livre \emph{Clean Architecture} -cite:{[}clean\_architecture{]}: - -\begin{quote} -Getting software right is hard: it takes knowledge and skills that most -young programmers don't take the time to develop. It requires a level of -discipline and dedication that most programmers never dreamed they'd -need. Mostly, it takes a passion for the craft and the desire to be a -professional. - ---- Robert C. Martin Clean Architecture -\end{quote} - -Le développement d'un logiciel nécessite une rigueur d'exécution et des -connaissances précises dans des domaines extrêmement variés. Il -nécessite également des intentions, des (bonnes) décisions et énormément -d'attention. Indépendamment de l'architecture que vous aurez choisie, -des technologies que vous aurez patiemment évaluées et mises en place, -une architecture et une solution peuvent être cassées en un instant, en -même temps que tout ce que vous aurez construit, dès que vous en aurez -détourné le regard. - -Un des objectifs ici est de placer les barrières et les gardes-fous (ou -plutôt, les "\textbf{garde-vous}"), afin de péréniser au maximum les -acquis, stabiliser les bases de tous les environnements (du -développement à la production) qui accueilliront notre application et -fiabiliser ainsi chaque étape de communication. - -Dans cette partie-ci, nous parlerons de \textbf{méthodes de travail}, -avec comme objectif d'éviter que l'application ne tourne que sur notre -machine et que chaque déploiement ne soit une plaie à gérer. Chaque mise -à jour doit être réalisable de la manière la plus simple possible, et -chaque étape doit être rendue la plus automatisée/automatisable -possible. Dans son plus simple élément, une application pourrait être -mise à jour simplement en envoyant son code sur un dépôt centralisé: ce -déclencheur doit démarrer une chaîne de vérification -d'utilisabilité/fonctionnalités/débuggabilité/sécurité, pour -immédiatement la mettre à disposition de nouveaux utilisateurs si toute -la chaîne indique que tout est OK. D'autres mécanismes fonctionnent -également, mais au plus les actions nécessitent d'actions humaines, -voire d'intervenants humains, au plus la probabilité qu'un problème -survienne est grande. - -Dans une version plus manuelle, cela pourrait se résumer à ces trois -étapes (la dernière étant formellement facultative): - -\begin{enumerate} -\def\labelenumi{\arabic{enumi}.} -\item - Démarrer un script, -\item - Prévoir un rollback si cela plante (et si cela a planté, préparer un - post-mortem de l'incident pour qu'il ne se produise plus) -\item - Se préparer une tisane en regardant nos flux RSS (pour peu que cette - technologie existe encore\ldots\hspace{0pt}). -\end{enumerate} - -\hypertarget{_pouxe9sie_de_la_programmation}{% -\section{Poésie de la -programmation}\label{_pouxe9sie_de_la_programmation}} - -\hypertarget{_complexituxe9_de_mccabe}{% -\subsection{Complexité de McCabe}\label{_complexituxe9_de_mccabe}} - -La \href{https://fr.wikipedia.org/wiki/Nombre_cyclomatique}{complexité -cyclomatique} (ou complexité de McCabe) peut s'apparenter à mesure de -difficulté de compréhension du code, en fonction du nombre -d'embranchements trouvés dans une même section. Quand le cycle -d'exécution du code rencontre une condition, il peut soit rentrer -dedans, soit passer directement à la suite. - -Par exemple: \begin{Shaded} \begin{Highlighting}[] @@ -441,89 +12,11 @@ Par exemple: TODO: faut vraiment reprendre un cas un peu plus lisible. Là, c'est naze. -La condition existe, mais nous ne passerons jamais dedans. A l'inverse, -le code suivant aura une complexité moisie à cause du nombre de -conditions imbriquées: -\begin{Shaded} -\begin{Highlighting}[] -\KeywordTok{def}\NormalTok{ compare(a, b, c, d, e):} - \ControlFlowTok{if}\NormalTok{ a }\OperatorTok{==}\NormalTok{ b:} - \ControlFlowTok{if}\NormalTok{ b }\OperatorTok{==}\NormalTok{ c:} - \ControlFlowTok{if}\NormalTok{ c }\OperatorTok{==}\NormalTok{ d:} - \ControlFlowTok{if}\NormalTok{ d }\OperatorTok{==}\NormalTok{ e:} - \BuiltInTok{print}\NormalTok{(}\StringTok{\textquotesingle{}Yeah!\textquotesingle{}}\NormalTok{)} - \ControlFlowTok{return} \DecValTok{1} -\end{Highlighting} -\end{Shaded} - -Potentiellement, les tests unitaires qui seront nécessaires à couvrir -tous les cas de figure seront au nombre de cinq: - -\begin{enumerate} -\def\labelenumi{\arabic{enumi}.} -\item - le cas par défaut (a est différent de b, rien ne se passe), -\item - le cas où \texttt{a} est égal à \texttt{b}, mais où \texttt{b} est - différent de \texttt{c} -\item - le cas où \texttt{a} est égal à \texttt{b}, \texttt{b} est égal à - \texttt{c}, mais \texttt{c} est différent de \texttt{d} -\item - le cas où \texttt{a} est égal à \texttt{b}, \texttt{b} est égal à - \texttt{c}, \texttt{c} est égal à \texttt{d}, mais \texttt{d} est - différent de \texttt{e} -\item - le cas où \texttt{a} est égal à \texttt{b}, \texttt{b} est égal à - \texttt{c}, \texttt{c} est égal à \texttt{d} et \texttt{d} est égal à - \texttt{e} -\end{enumerate} - -La complexité cyclomatique d'un bloc est évaluée sur base du nombre -d'embranchements possibles; par défaut, sa valeur est de 1. Si nous -rencontrons une condition, elle passera à 2, etc. - -Pour l'exemple ci-dessous, nous allons devoir vérifier au moins chacun -des cas pour nous assurer que la couverture est complète. Nous devrions -donc trouver: - -\begin{enumerate} -\def\labelenumi{\arabic{enumi}.} -\item - Un test où rien de se passe (\texttt{a\ !=\ b}) -\item - Un test pour entrer dans la condition \texttt{a\ ==\ b} -\item - Un test pour entrer dans la condition \texttt{b\ ==\ c} -\item - Un test pour entrer dans la condition \texttt{c\ ==\ d} -\item - Un test pour entrer dans la condition \texttt{d\ ==\ e} -\end{enumerate} - -Nous avons donc bien besoin de minimum cinq tests pour couvrir -l'entièreté des cas présentés. - -Le nombre de tests unitaires nécessaires à la couverture d'un bloc -fonctionnel est au minimum égal à la complexité cyclomatique de ce bloc. -Une possibilité pour améliorer la maintenance du code est de faire -baisser ce nombre, et de le conserver sous un certain seuil. Certains -recommandent de le garder sous une complexité de 10; d'autres de 5. - -Il est important de noter que refactoriser un bloc pour en extraire une -méthode n'améliorera pas la complexité cyclomatique globale de -l'application. Nous visons ici une amélioration \textbf{locale}. \hypertarget{_conclusion}{% \subsection{Conclusion}\label{_conclusion}} -\begin{quote} -The primary cost of maintenance is in spelunking and risk -cite:{[}clean\_architecture(139){]} - ---- Robert C. Martin -\end{quote} En ayant connaissance de toutes les choses qui pourraient être modifiées par la suite, l'idée est de pousser le développement jusqu'au point où @@ -1946,39 +1439,6 @@ considérés comme volatiles \hypertarget{_architecture}{% \section{Architecture}\label{_architecture}} -\begin{quote} -If you think good architecture is expensive, try bad architecture - ---- Brian Foote and Joseph Yoder -\end{quote} - -Au delà des principes dont il est question plus haut, c'est dans les -ressources proposées et les cas démontrés que l'on comprend leur -intérêt: plus que de la définition d'une architecture adéquate, c'est -surtout dans la facilité de maintenance d'une application que ces -principes s'identifient. - -Une bonne architecture va rendre le système facile à lire, facile à -développer, facile à maintenir et facile à déployer. L'objectif ultime -étant de minimiser le coût de maintenance et de maximiser la -productivité des développeurs. Un des autres objectifs d'une bonne -architecture consiste également à se garder le plus d'options possibles, -et à se concentrer sur les détails (le type de base de données, la -conception concrète, \ldots\hspace{0pt}), le plus tard possible, tout en -conservant la politique principale en ligne de mire. Cela permet de -délayer les choix techniques à «~plus tard~», ce qui permet également de -concrétiser ces choix en ayant le plus d'informations possibles -cite:{[}clean\_architecture(137-141){]} - -Derrière une bonne architecture, il y a aussi un investissement quant -aux ressources qui seront nécessaires à faire évoluer l'application: ne -pas investir dès qu'on le peut va juste lentement remplir la case de la -dette technique. - -Une architecture ouverte et pouvant être étendue n'a d'intérêt que si le -développement est suivi et que les gestionnaires (et architectes) -s'engagent à économiser du temps et de la qualité lorsque des -changements seront demandés pour l'évolution du projet. \hypertarget{_politiques_et_ruxe8gles_muxe9tiers}{% \subsection{Politiques et règles @@ -1990,131 +1450,21 @@ TODO: Un p'tit bout à ajouter sur les méthodes de conception ;) \subsection{Considération sur les frameworks}\label{_considuxe9ration_sur_les_frameworks}} -\begin{quote} -Frameworks are tools to be used, not architectures to be conformed to. -Your architecture should tell readers about the system, not about the -frameworks you used in your system. If you are building a health care -system, then when new programmers look at the source repository, their -first impression should be, «~oh, this is a health care system~». Those -new programmers should be able to learn all the use cases of the system, -yet still not know how the system is delivered. ---- Robert C. Martin Clean Architecture -\end{quote} -Le point soulevé ci-dessous est qu'un framework n'est qu'un outil, et -pas une obligation de structuration. L'idée est que le framework doit se -conformer à la définition de l'application, et non l'inverse. Dans le -cadre de l'utilisation de Django, c'est un point critique à prendre en -considération: une fois que vous aurez fait ce choix, vous aurez -extrêmement difficile à faire machine arrière: -\begin{itemize} -\item - Votre modèle métier sera largement couplé avec le type de base de - données (relationnelle, indépendamment -\item - Votre couche de présentation sera surtout disponible au travers d'un - navigateur -\item - Les droits d'accès et permissions seront en grosse partie gérés par le - frameworks -\item - La sécurité dépendra de votre habilité à suivre les versions -\item - Et les fonctionnalités complémentaires (que vous n'aurez pas voulu/eu - le temps de développer) dépendront de la bonne volonté de la - communauté -\end{itemize} -Le point à comprendre ici n'est pas que "Django, c'est mal", mais qu'une -fois que vous aurez défini la politique, les règles métiers, les données -critiques et entités, et que vous aurez fait le choix de développer en -âme et conscience votre nouvelle création en utilisant Django, vous -serez bon gré mal gré, contraint de continuer avec. Cette décision ne -sera pas irrévocable, mais difficile à contourner. -\begin{quote} -At some point in their history most DevOps organizations were hobbled by -tightly-coupled, monolithic architectures that while extremely -successfull at helping them achieve product/market fit - put them at -risk of organizational failure once they had to operate at scale (e.g. -eBay's monolithic C++ application in 2001, Amazon's monolithic OBIDOS -application in 2001, Twitter's monolithic Rails front-end in 2009, and -LinkedIn's monolithic Leo application in 2011). In each of these cases, -they were able to re-architect their systems and set the stage not only -to survice, but also to thrise and win in the marketplace -\end{quote} -cite:{[}devops\_handbook(182){]} -Ceci dit, Django compense ses contraintes en proposant énormément de -flexibilité et de fonctionnalités \textbf{out-of-the-box}, c'est-à-dire -que vous pourrez sans doute avancer vite et bien jusqu'à un point de -rupture, puis revoir la conception et réinvestir à ce moment-là, mais en -toute connaissance de cause. -\begin{quote} -When any of the external parts of the system become obsolete, such as -the database, or the web framework, you can replace those obsolete -elements with a minimum of fuss. ---- Robert C. Martin Clean Architecture -\end{quote} - -Avec Django, la difficulté à se passer du framework va consister à -basculer vers «~autre chose~» et a remplacer chacune des tentacules qui -aura pousser partout dans l'application. - -A noter que les services et les «~architectures orientées services~» ne -sont jamais qu'une définition d'implémentation des frontières, dans la -mesure où un service n'est jamais qu'une fonction appelée au travers -d'un protocole (rest, soap, \ldots\hspace{0pt}). Une application -monolotihique sera tout aussi fonctionnelle qu'une application découpée -en microservices. (Services: great and small, page 243). \hypertarget{_un_point_sur_linversion_de_duxe9pendances}{% \subsection{Un point sur l'inversion de dépendances}\label{_un_point_sur_linversion_de_duxe9pendances}} -Dans la partie SOLID, nous avons évoqué plusieurs principes de -développement. Django est un framework qui évolue, et qui a pu présenter -certains problèmes liés à l'un de ces principes. -Les link:release -notes{[}\url{https://docs.djangoproject.com/en/2.0/releases/2.0/}{]} de -Django 2.0 date de décembre 2017; parmi ces notes, l'une d'elles cite -l'abandon du support d'link:Oracle -11.2{[}\url{https://docs.djangoproject.com/en/2.0/releases/2.0/\#dropped-support-for-oracle-11-2}{]}. -En substance, cela signifie que le framework se chargeait lui-même de -construire certaines parties de requêtes, qui deviennent non -fonctionnelles dès lors que l'on met le framework ou le moteur de base -de données à jour. Réécrit, cela signifie que: - -\begin{enumerate} -\def\labelenumi{\arabic{enumi}.} -\item - Si vos données sont stockées dans un moteur géré par Oracle 11.2, vous - serez limité à une version 1.11 de Django -\item - Tandis que si votre moteur est géré par une version ultérieure, le - framework pourra être mis à jour. -\end{enumerate} - -Nous sommes dans un cas concret d'inversion de dépendances ratée: le -framework (et encore moins vos politiques et règles métiers) ne -devraient pas avoir connaissance du moteur de base de données. Pire, vos -politiques et données métiers ne devraient pas avoir connaissance -\textbf{de la version} du moteur de base de données. - -En conclusion, le choix d'une version d'un moteur technique (\textbf{la -base de données}) a une incidence directe sur les fonctionnalités mises -à disposition par votre application, ce qui va à l'encontre des 12 -facteurs (et des principes de développement). - -Ce point sera rediscuté par la suite, notamment au niveau de l'épinglage -des versions, de la reproduction des environnements et de -l'interdépendance entre des choix techniques et fonctionnels. \hypertarget{_tests_et_intuxe9gration}{% \section{Tests et intégration}\label{_tests_et_intuxe9gration}} diff --git a/sources/chapters/maintenability.tex b/sources/chapters/maintenability.tex deleted file mode 100644 index c5cff07..0000000 --- a/sources/chapters/maintenability.tex +++ /dev/null @@ -1,61 +0,0 @@ -\chapter{Fiabilité, évolutivité et maintenabilité} - -\begin{quote} -The primary cost of maintenance is in spelunking and risk - \cite[139]{clean_architecture} - ---- Robert C. Martin -\end{quote} - -\section{Complexité cyclomatique} - -La \href{https://fr.wikipedia.org/wiki/Nombre_cyclomatique}{complexité cyclomatique} (ou complexité de McCabe) peut s'apparenter à mesure de difficulté de compréhension du code, en fonction du nombre d'embranchements trouvés dans une même section. -Quand le cycle d'exécution du code rencontre une condition, cette condition peut être évalue à VRAI ou à FAUX. -L'exécution du code dispose donc de deux embranchements, correspondant chacun à un résultat de cette condition. - -Le code suivant a une complexité cyclomatique 1; il s'agit du cas le plus simple que nous pouvons implémenter: l'exécution du code rentre dans la fonction (il y a un seul embranchement), et aucun bloc conditionnel n'est présent sur son chemin. -La complexité reste de 1. - -\begin{listing}[hbpt] - \begin{minted}{Python} - from datetime import date - - def print_current_date(): - print(date.today()) - \end{minted} -\end{listing} - -Si nous complexifions cette fonction en vérifiant (par exemple) le jour de la semaine, nous aurons notre embranchement initial (l'impression à l'écran de la date du jour), mais également un second embranchement qui vérifiera si cette date correspond à un lundi: - -\begin{listing} - \begin{minted}{Python} - from datetime import date - - def print_current_date_if_monday(): - if date.today().weekday() == 0: - print("Aujourd'hui, c'est lundi!") - print(date.today()) - \end{minted} -\end{listing} - -La complexité cyclomatique d'un bloc est évaluée sur base du nombre d'embranchements possibles; par défaut, sa valeur est de 1. -Si nous rencontrons une condition, elle passera à 2, etc. -Cette complexité est liée à deux concepts: - -\begin{itemize} - \item \textbf{La lisibilité du code}: au plus la complexité cyclomatique sera élevée, au plus le code sera compliqué à comprendre en première instance. Il sera composé de plusieurs conditions, éventuellement imbriquées, il débordera probablement de la hauteur que votre écran sera capable d'afficher - \item \textbf{Les tests unitaires}: pour nous assurer d'une couverture de code correcte, il sera nécessaire de couvrir tous les embranchements présentés. Connaître la complexité permet de savoir combien de tests devront être écrits pour assurer une couverture complète de tous les cas pouvant se présenter. -\end{itemize} - -\subsection{Tests unitaires} - -Le nombre de tests unitaires nécessaires à la couverture d'un bloc fonctionnel est au minimum égal à la complexité cyclomatique de ce bloc. -Une possibilité pour améliorer la maintenance du code est de faire baisser ce nombre, et de le conserver sous un certain seuil. -Certains recommandent de le garder sous une complexité de 10; d'autres de 5. - -\subsection{Lisibilité du code} - -Il est important de noter que refactoriser un bloc pour en extraire une méthode n'améliorera pas la complexité cyclomatique globale de -l'application. -Nous visons ici une amélioration \textbf{locale}. -