Complete references after reviewing each page
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Fred Pauchet 2021-09-30 20:38:47 +02:00
parent 059d7c1f99
commit c28d0b4cdb
7 changed files with 150 additions and 90 deletions

View File

@ -7,9 +7,14 @@ Cédric Declerfayt <jaguarondi27@gmail.com>; Fred Pauchet <fred@grimbox.be>
:chapter-label: Chapitre
:preface-title: Préface
:bibtex-file: source/references.bib
:bibtex-order: alphabetical
:bibtex-throw: true
:source-highlighter: rouge
:icons: font
"The only way to go fast, is to go well"
-- Robert C. Martin
Nous n'allons pas vous mentir: il existe enormément de tutoriaux très bien réalisés sur "_Comment réaliser une application Django_" et autres "_Déployer votre code en 2 minutes_".
Nous nous disions juste que ces tutoriaux restaient relativement haut-niveaux et se limitaient à un contexte donné, et ne préparaient pas réellement à la maintenance et au suivi d'une application.
@ -46,7 +51,23 @@ Nous aborderons les concepts clés qui permettent à une application de rester m
*Dans la quatrième partie*, nous mettrons ces concepts en pratique en présentant le développement de deux "vraies" applications: définition des tables, gestion des utilisateurs, ... et mise à disposition!
Et tout ça à un seul et même endroit.footnote:[Avec même un peu d'https://www.xkcd.com[XKCD]] et de Calvin & Hobbes dedans.
footnote:[Avec même un peu d'https://www.xkcd.com[XKCD] et de Calvin & Hobbes dedans]
*Qui cela peut intéresser*
*Ce que ce livre couvre*
*Pour aller plus loin*
*Conventions*
*Let's keep in touch*
Bonne lecture.

View File

@ -19,7 +19,7 @@ Lapplication des principes présentés et agrégés ci-dessous permet surtout
sans aller jusquau « *You Ain't Gonna Need It* » (ou *YAGNI*), qui consiste à surcharger tout développement avec des fonctionnalités non demandées, juste « au cas ou ».
Pour paraphraser une partie de lintroduction du livre _Clean Architecture_ cite:[clean_architecture]:
[quote, Robert C. Martin, Clean Architecture]
[quote]
Getting software right is hard: it takes knowledge and skills that most young programmers dont take the time to develop.
It requires a level of discipline and dedication that most programmers never dreamed theyd need.
Mostly, it takes a passion for the craft and the desire to be a professional.
@ -34,11 +34,14 @@ 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 "*garde-vous*"), afin de péréniser au maximum les acquis, stabiliser les bases de tous les environnements (du développement à la production) qui pourraient accueillir notre application et fiabiliser les étapes de communication.
Dans cette partie, nous allons parler de *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:
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émarrer un script,
. 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)
. se préparer une tisane en regardant nos flux RSS (si cette technologie existe encore...).
Dans une version plus manuelle, cela pourrait se résumer à ces trois étapes (la dernière étant formellement facultative):
. Démarrer un script,
. 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)
. Se préparer une tisane en regardant nos flux RSS (pour peu que cette technologie existe encore...).
NOTE: 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)

View File

@ -1,25 +1,38 @@
== Python
Le langage https://www.python.org/[Python] est un https://docs.python.org/3/faq/general.html#what-is-python[langage de programmation] interprété, interactif, orienté objet (souvent), fonctionnel (parfois), open source, multi-plateformes, flexible, facile à apprendre et difficile à maîtriser.
Le langage https://www.python.org/[Python] est un https://docs.python.org/3/faq/general.html#what-is-python[langage de programmation] interprété, interactif, amusant, orienté objet (souvent), fonctionnel (parfois), open source, multi-plateformes, flexible, facile à apprendre et difficile à maîtriser.
.https://xkcd.com/353/
image::images/xkcd-353-python.png[]
A première vue, certains concepts restent difficiles à aborder: l'indentation définit l'étendue d'un bloc (classe, fonction, méthode, boucle, condition, ...), il n'y a pas de typage fort des variables et le compilateur n'est pas là pour assurer le filet de sécurité avant la mise en production (puisqu'il n'y a pas de compilateur 😛).
A première vue, et suivants les autres langages que vous connaitriez ou auriez déjà abordé, certains concepts restent difficiles à aborder: l'indentation définit l'étendue d'un bloc (classe, fonction, méthode, boucle, condition, ...), il n'y a pas de typage fort des variables et le compilateur n'est pas là pour assurer le filet de sécurité avant la mise en production (puisqu'il n'y a pas de compilateur 😛).
Et malgré ces quelques points, Python reste un langage généraliste accessible et "bon partout", et de pouvoir se reposer sur un écosystème stable et fonctionnel.
Il fonctionne avec un système d'améliorations basées sur des propositions: les PEP, ou "**Python Enhancement Proposal**".
Chacune d'entre elles doit être approuvée par le http://fr.wikipedia.org/wiki/Benevolent_Dictator_for_Life[Benevolent Dictator For Life].
Si vous avez besoin d'un aide-mémoire ou d'une liste exhaustive des types et structures de données du langage, référez-vous au lien suivant: https://gto76.github.io/python-cheatsheet/[Python Cheat Sheet].
NOTE: Le langage Python utilise un typage dynamique appelé https://fr.wikipedia.org/wiki/Duck_typing[*duck typing*]: "_When I see a bird that quacks like a duck, walks like a duck, has feathers and webbed feet and associates with ducks — Im certainly going to assume that he is a duck_"
NOTE: Le langage Python utilise un typage dynamique appelé https://fr.wikipedia.org/wiki/Duck_typing[*duck typing*]: "_When I see a bird that quacks like a duck, walks like a duck, has feathers and webbed feet and associates with ducks — Im certainly going to assume that he is a duck_"
Source: http://en.wikipedia.org/wiki/Duck_test[Wikipedia].
Les morceaux de code que vous trouverez ci-dessous seront développés pour Python3.9+ et Django 3.2+.
Les morceaux de code que vous trouverez ci-dessous seront développés pour Python3.9+ et Django 3.2+.
Ils nécessiteront peut-être quelques adaptations pour fonctionner sur une version antérieure.
==== The Zen of Python
=== Eléments de langage
En fonction de votre niveau d'apprentissage du langage, plusieurs ressources pourraient vous aider:
* *Pour les débutants*, https://automatetheboringstuff.com/[Automate the Boring Stuff with Python] cite:[boring_stuff], aka. _Practical Programming for Total Beginners_
* *Pour un (gros) niveau au dessus* et pour un état de l'art du langage, nous ne pouvons que vous recommander le livre Expert Python Programming cite:[expert_python], qui aborde énormément d'aspects du langage en détails (mais pas toujours en profondeur): les différents types d'interpréteurs, les éléments de langage avancés, différents outils de productivité, métaprogrammation, optimisation de code, programmation orientée évènements, multithreading et concurrence, tests, ...
A ce jour, c'est le concentré de sujets liés au langage le plus intéressant qui ait pu arriver entre nos mains.
En parallèle, si vous avez besoin d'un aide-mémoire ou d'une liste exhaustive des types et structures de données du langage, référez-vous au lien suivant: https://gto76.github.io/python-cheatsheet/[Python Cheat Sheet].
=== The Zen of Python
[source,python]
----
@ -52,13 +65,13 @@ Namespaces are one honking great idea -- let's do more of those!
----
==== PEP8 - Style Guide for Python Code
=== PEP8 - Style Guide for Python Code
La première PEP qui va nous intéresser est la https://www.python.org/dev/peps/pep-0008/[PEP 8 -- Style Guide for Python Code]. Elle spécifie comment du code Python doit être organisé ou formaté, quelles sont les conventions pour lindentation, le nommage des variables et des classes, ...
En bref, elle décrit comment écrire du code proprement, afin que dautres développeurs puissent le reprendre facilement, ou simplement que votre base de code ne dérive lentement vers un seuil de non-maintenabilité.
Dans cet objectif, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: pep8.
Pour l'installer, passez par pip. Lancez ensuite la commande pep8 suivie du chemin à analyser (`.`, le nom d'un répertoire, le nom d'un fichier `.py`, ...).
Dans cet objectif, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: pep8.
Pour l'installer, passez par pip. Lancez ensuite la commande pep8 suivie du chemin à analyser (`.`, le nom d'un répertoire, le nom d'un fichier `.py`, ...).
Si vous souhaitez uniquement avoir le nombre d'erreur de chaque type, saisissez les options `--statistics -qq`.
[source,bash]
@ -78,7 +91,7 @@ $ pep8 . --statistics -qq
Si vous ne voulez pas être dérangé sur votre manière de coder, et que vous voulez juste avoir un retour sur une analyse de votre code, essayez `pyflakes`: cette librairie analysera vos sources à la recherche de sources d'erreurs possibles (imports inutilisés, méthodes inconnues, etc.).
==== PEP257 - Docstring Conventions
=== PEP257 - Docstring Conventions
Python étant un langage interprété fortement typé, il est plus que conseillé, au même titre que les tests unitaires que nous verrons plus bas, de documenter son code.
Cela impose une certaine rigueur, mais améliore énormément la qualité (et la reprise) du code par une tierce personne.
@ -204,7 +217,7 @@ Nous trouvons des erreurs:
* de *conventions*: le nombre de lignes qui séparent deux fonctions, le nombre d'espace après un opérateur, une ligne vide à la fin du fichier, ... Ces _erreurs_ n'en sont pas vraiment, elles indiquent juste de potentiels problèmes de communication si le code devait être lu ou compris par une autre personne.
* de *définition*: une variable assignée mais pas utilisée ou une lexème non trouvé. Cette dernière information indique clairement un bug potentiel. Ne pas en tenir compte nuira sans doute à la santé de votre code (et risque de vous réveiller à cinq heures du mat', quand votre application se prendra méchamment les pieds dans le tapis).
L'étape d'après consiste à invoquer pylint.
L'étape d'après consiste à invoquer pylint.
Lui, il est directement moins conciliant:
@ -232,7 +245,7 @@ test.py:16:10: E0602: Undefined variable 'Get_Today' (undefined-variable)
Your code has been rated at -5.45/10
----
En gros, j'ai programmé comme une grosse bouse anémique (et oui: le score d'évaluation du code permet bien d'aller en négatif).
En gros, j'ai programmé comme une grosse bouse anémique (et oui: le score d'évaluation du code permet bien d'aller en négatif).
En vrac, nous trouvons des problèmes liés:
* au nommage (C0103) et à la mise en forme (C0305, C0326, W0105)
@ -256,10 +269,10 @@ TODO: Voir si la sortie de pylint est obligatoirement 0 s'il y a un warning
TODO: parler de `pylint --errors-only`
==== Formatage de code
=== Formatage de code
Nous avons parlé ci-dessous de style de codage pour Python (PEP8), de style de rédaction pour la documentation (PEP257), d'un _linter_ pour nous indiquer quels morceaux de code doivent absolument être revus, ...
Reste que ces tâches sont [line-through]#parfois# (très) souvent fastidieuses: écrire un code propre et systématiquement cohérent est une tâche ardue.
Reste que ces tâches sont [line-through]#parfois# (très) souvent fastidieuses: écrire un code propre et systématiquement cohérent est une tâche ardue.
Heureusement, il existe des outils pour nous aider (un peu).
A nouveau, il existe plusieurs possibilités de formatage automatique du code.
@ -273,18 +286,18 @@ Mais ce formatage conviendra dans 97,83% des cas (au moins).
>
> Black makes code review faster by producing the smallest diffs possible. Blackened code looks the same regardless of the project youre reading. Formatting becomes transparent after a while and you can focus on the content instead.
Traduit rapidement à partir de la langue de Batman: "_En utilisant Black, vous cédez le contrôle sur le formatage de votre code. En retour, Black vous fera gagner un max de temps, diminuera votre charge mentale et fera revenir l'être aimé_".
Traduit rapidement à partir de la langue de Batman: "_En utilisant Black, vous cédez le contrôle sur le formatage de votre code. En retour, Black vous fera gagner un max de temps, diminuera votre charge mentale et fera revenir l'être aimé_".
Mais la partie réellement intéressante concerne le fait que "_Tout code qui sera passé par Black aura la même forme, indépendamment du project sur lequel vous serez en train de travailler. L'étape de formatage deviendra transparente, et vous pourrez vous concentrer sur le contenu_".
==== Complexité cyclomatique
=== Complexité cyclomatique
A nouveau, un greffon pour `flake8` existe et donnera une estimation de la complexité de McCabe pour les fonctions trop complexes. Installez-le avec `pip install mccabe`, et activez-le avec le paramètre `--max-complexity`. Toute fonction dans la complexité est supérieure à cette valeur sera considérée comme trop complexe.
==== Typage statique - https://www.python.org/dev/peps/pep-0585/[PEP585]
=== Typage statique - https://www.python.org/dev/peps/pep-0585/[PEP585]
Nous vous disions ci-dessus que Python était un langage dynamique interprété.
Nous vous disions ci-dessus que Python était un langage dynamique interprété.
Concrètement, cela signifie que des erreurs pouvant être détectées à la compilation avec d'autres langages, ne le sont pas avec Python.
Il existe cependant une solution à ce problème, sous la forme de http://mypy-lang.org/[Mypy], qui peut (sous vous le souhaitez ;-)) vérifier une forme de typage statique de votre code source, grâce à une expressivité du code, basée sur des annotations (facultatives, elles aussi).
@ -305,7 +318,7 @@ if __name__ == "__main__":
print(first_int_elem(['a', 'b', 'c']))
----
Est-ce que le code ci-dessous fonctionne correctement ?
Est-ce que le code ci-dessous fonctionne correctement ?
*Oui*:
[source,bash]
@ -333,7 +346,7 @@ Found 4 errors in 1 file (checked 1 source file)
Pour corriger ceci, nous devons:
. Importer le type `Optional` et l'utiliser en sortie de notre fonction `first_int_elem`
. Eviter de lui donner de
. Eviter de lui donner de
mauvais paramètres ;-)
[source,python]
@ -372,17 +385,17 @@ class TestModel(TestCase):
raise NotImplementedError('Not implemented yet')
----
Idéalement, chaque fonction ou méthode doit être testée afin de bien en valider le fonctionnement, indépendamment du reste des composants. Cela permet d'isoler chaque bloc de manière unitaire, et permet de ne pas rencontrer de régression lors de l'ajout d'une nouvelle fonctionnalité ou de la modification d'une existante.
Idéalement, chaque fonction ou méthode doit être testée afin de bien en valider le fonctionnement, indépendamment du reste des composants. Cela permet d'isoler chaque bloc de manière unitaire, et permet de ne pas rencontrer de régression lors de l'ajout d'une nouvelle fonctionnalité ou de la modification d'une existante.
Il existe plusieurs types de tests (intégration, comportement, ...); on ne parlera ici que des tests unitaires.
Avoir des tests, c'est bien.
S'assurer que tout est testé, c'est mieux.
Avoir des tests, c'est bien.
S'assurer que tout est testé, c'est mieux.
C'est là qu'il est utile d'avoir le pourcentage de code couvert par les différents tests, pour savoir ce qui peut être amélioré.
Comme indiqué ci-dessus, Django propose son propre cadre de tests, au travers du package `django.tests`.
Une bonne pratique (parfois discutée) consiste cependant à switcher vers `pytest`, qui présente quelques avantages:
* Une syntaxe plus concise (au prix de https://docs.pytest.org/en/reorganize-docs/new-docs/user/naming_conventions.html[quelques conventions], même si elles restent configurables): un test est une fonction, et ne doit pas obligatoirement faire partie d'une classe héritant de `TestCase` - la seule nécessité étant que cette fonction fasse partie d'un module commençant ou finissant par "test" (`test_example.py` ou `example_test.py`).
* Une syntaxe plus concise (au prix de https://docs.pytest.org/en/reorganize-docs/new-docs/user/naming_conventions.html[quelques conventions], même si elles restent configurables): un test est une fonction, et ne doit pas obligatoirement faire partie d'une classe héritant de `TestCase` - la seule nécessité étant que cette fonction fasse partie d'un module commençant ou finissant par "test" (`test_example.py` ou `example_test.py`).
* Une compatibilité avec du code Python "classique" - vous ne devrez donc retenir qu'un seul ensemble de commandes ;-)
* Des _fixtures_ faciles à réutiliser entre vos différents composants
* Une compatibilité avec le reste de l'écosystème, dont la couverture de code présentée ci-dessous.
@ -395,7 +408,7 @@ def test_add():
assert 1 + 1 == "argh"
----
Forcément, cela va planter.
Forcément, cela va planter.
Pour nous en assurer (dès fois que quelqu'un en doute), il nous suffit de démarrer la commande `pytest`:
[source,bash]
@ -426,13 +439,13 @@ FAILED gwift/test_models.py::test_basic_add - AssertionError: assert (1 + 1) ==
==== Couverture de code
La couverture de code est une analyse qui donne un pourcentage lié à la quantité de code couvert par les tests.
Attention qu'il ne s'agit pas de vérifier que le code est **bien** testé, mais juste de vérifier **quelle partie** du code est testée.
La couverture de code est une analyse qui donne un pourcentage lié à la quantité de code couvert par les tests.
Attention qu'il ne s'agit pas de vérifier que le code est **bien** testé, mais juste de vérifier **quelle partie** du code est testée.
Le paquet `coverage` se charge d'évaluer le pourcentage de code couvert par les tests.
Avec `pytest`, il convient d'utiliser le paquet https://pypi.org/project/pytest-cov/[`pytest-cov`], suivi de la commande `pytest --cov=gwift tests/`.
Si vous préférez rester avec le cadre de tests de Django, vous pouvez passer par le paquet https://pypi.org/project/django-coverage-plugin/[django-coverage-plugin] Ajoutez-le dans le fichier `requirements/base.txt`, et lancez une couverture de code grâce à la commande `coverage`.
Si vous préférez rester avec le cadre de tests de Django, vous pouvez passer par le paquet https://pypi.org/project/django-coverage-plugin/[django-coverage-plugin] Ajoutez-le dans le fichier `requirements/base.txt`, et lancez une couverture de code grâce à la commande `coverage`.
La configuration peut se faire dans un fichier `.coveragerc` que vous placerez à la racine de votre projet, et qui sera lu lors de l'exécution.
[source,bash]
@ -553,7 +566,7 @@ RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update \
&& apt-get install -y msodbcsql17 unixodbc-dev
# clean the install.
RUN apt-get -y clean
@ -687,8 +700,8 @@ Les plus connus sont https://www.gitflow.com/[Gitflow] et https://www.reddit.com
==== Décrire ses changements
La description d'un changement se fait _via_ la commande `git commit`.
Il est possible de lui passer directement le message associé à ce changement grâce à l'attribut `-m`, mais c'est une pratique relativement déconseillée: un _commit_ ne doit effectivement pas obligatoirement être décrit sur une seule ligne.
La description d'un changement se fait _via_ la commande `git commit`.
Il est possible de lui passer directement le message associé à ce changement grâce à l'attribut `-m`, mais c'est une pratique relativement déconseillée: un _commit_ ne doit effectivement pas obligatoirement être décrit sur une seule ligne.
Une description plus complète, accompagnée des éventuels tickets ou références, sera plus complète, plus agréable à lire, et plus facile à revoir pour vos éventuels relecteurs.
De plus, la plupart des plateformes de dépôts présenteront ces informations de manière ergonomique. Par exemple:
@ -737,14 +750,14 @@ La syntaxe de ce fichier `Vagrantfile` est en https://www.ruby-lang.org/en/[Ruby
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
config.vm.provider "virtualbox" do |vb|
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "1024"
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y nginx
@ -752,7 +765,7 @@ Vagrant.configure("2") do |config|
end
----
Dans le fichier ci-dessus, nous créons:
Dans le fichier ci-dessus, nous créons:
* Une nouvelle machine virtuelle (ie. _invitée_) sous Ubuntu Bionic Beaver, en x64
* Avec une correspondance du port `80` de la machine vers le port `8080` de l'hôte, en limitant l'accès à celui-ci - accédez à `localhost:8080` et vous accéderez au port `80` de la machine virtuelle.
@ -831,7 +844,7 @@ services:
depends_on:
- redis
- postgres
ports: []
command: /start-celeryworker
@ -842,7 +855,7 @@ services:
depends_on:
- redis
- postgres
ports: []
command: /start-celerybeat
@ -932,4 +945,4 @@ WORKDIR /app
ENTRYPOINT ["/entrypoint"]
----
NOTE: Voir comment nous pouvons intégrer toutes ces commandes au niveau de la CI et au niveau du déploiement (Docker-compose ?)
NOTE: Voir comment nous pouvons intégrer toutes ces commandes au niveau de la CI et au niveau du déploiement (Docker-compose ?)

View File

@ -1,26 +1,24 @@
== Construire des applications
== Architecture
[quote, Robert C. Martin, Clean Architecture, Chapitre 15, What is architecture ?, page 137]
A software system that is hard to develop is not likely to have a long and healthy lifetime
=== Bien structurées
include::clean_architecture.adoc[]
=== Evolutives
=== Evolutions
include::12-factors.adoc[]
=== Maintenables
=== Maintenabilité
include::maintainable-applications.adoc[]
include::mccabe.adoc[]
=== Robustes, flexibles
=== Robustesse et flexibilité
include::solid.adoc[]
=== Et testées
=== Intégrées
[quote, Robert C. Martin, Clean Architecture, page 203, Inner circle are policies, page 250, Chapitre 28 - The Boundaries]
Tests are part of the system.

View File

@ -12,23 +12,17 @@ plus que de la définition dune architecture adéquate, cest surtout dans
dune application que ces principes sidentifient.
Derrière une bonne architecture, il y a aussi un investissement quant aux ressources qui seront nécessaires
à faire évoluer lapplication.
Ne pas investir dès quon le peut va juste lentement remplir la case de la dette technique.
à faire évoluer lapplication: ne pas investir dès quon le peut va juste lentement remplir la case de la dette technique.
Good architecture makes the system easy to understand, easy to develop, easy to maintain and easy to deploy.
The ultimate goal is to minimize the lifetime cost of the system and to maximize programmer productivity.
-- Robert C. Martin, Clean Architecture, Chapitre 15, what is architecture ?, page 137
Lobjectif d'une bonne architecture est également de garder le plus doptions possibles,
de se concentrer sur les détails (le type de base de données, la conception concrète, ...),
Une bonne architecture va également 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 doptions possibles,
et à se concentrer sur les détails (le type de base de données, la conception concrète, ...),
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 dinformations possibles.
-- Robert C. Martin, Clean Architecture, page 141 - What is architecture ?
en ayant le plus dinformations possibles cite:[clean_architecture(137-141)]
Une architecture ouverte et pouvant être étendue na dintérêt que si le
développement est suivi et que les gestionnaires (et architectes) sengagent à économiser du temps
et de la qualité lorsque des changements seront demandés pour lévolution du projet.
Une architecture ouverte et pouvant être étendue na dintérêt que si le développement est suivi et que les gestionnaires (et architectes) sengagent à économiser du temps et de la qualité lorsque des changements seront demandés pour lévolution du projet.
==== Politiques et règles métiers
@ -63,8 +57,7 @@ votre nouvelle création en utilisant Django, vous serez bon gré mal gré, cont
Cette décision ne sera pas irrévocable, mais difficile à contourner.
> 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
> The DevOps Handbook, Part III - The Principles of Flow - Architect for low-risk release (page 182)
> 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 cite:[devops_handbook(182)]
Ceci dit, Django compense ses contraintes en proposant énormément de flexibilité et de fonctionnalités
*out-of-the-box*, c'est-à-dire que vous pourrez sans doute avancer vite et bien jusqu'à un point de rupture,

View File

@ -1,41 +1,33 @@
=== Développements
=== Maintenance
[quote]
----
The primary cost of maintenance is in spelunking and risk
-- Robert C. Martin, Clean Architecture, page 139
----
[quote, Robert C. Martin]
The primary cost of maintenance is in spelunking and risk cite:[clean_architecture(139)]
En ayant connaissance de toutes les choses qui pourraient être modifiées par la suite,
lidée est de pousser le développement jusquau point où un service pourrait être nécessaire.
A ce stade, larchitecture nécessitera des modifications, mais aura déjà intégré le fait que cette possibilité existe.
Nous nallons donc pas jusquau point où le service doit être créé (même sil peut ne pas être nécessaire),
ni à lextrême au fait dignorer quun service pourrait être nécessaire, mais nous aboutissons à une forme de compromis.
Une forme de comportement de Descartes, qui ne croit pas en dieu, mais qui envisage quand même cette possibilité,
En ayant connaissance de toutes les choses qui pourraient être modifiées par la suite,
lidée est de pousser le développement jusquau point où un service pourrait être nécessaire.
A ce stade, larchitecture nécessitera des modifications, mais aura déjà intégré le fait que cette possibilité existe.
Nous nallons donc pas jusquau point où le service doit être créé (même sil peut ne pas être nécessaire),
ni à lextrême au fait dignorer quun service pourrait être nécessaire, mais nous aboutissons à une forme de compromis.
Une forme de comportement de Descartes, qui ne croit pas en Dieu, mais qui envisage quand même cette possibilité,
ce qui lui ouvre le maximum de portes 🙃
Avec cette approche, les composants sont déjà découplés au niveau du code source, ce qui pourrait savérer suffisant
jusquau stade où une modification ne pourra plus faire reculer léchéance.
Avec cette approche, les composants sont déjà découplés au niveau du code source, ce qui pourrait savérer suffisant
jusquau stade où une modification ne pourra plus faire reculer léchéance.
En terme de découpe, les composants peuvent lêtre aux niveaux suivants:
@ code source
@ déploiement, au travers de dll, jar, linked libraries, … voire au travers de threads ou de processus locaux.
@ déploiement, au travers de dll, jar, linked libraries, … voire au travers de threads ou de processus locaux.
@ services
Pour cette section, nous nous basons sur un résumé de l'ebook **Building Maintenable Software** disponible chez http://shop.oreilly.com/product/0636920049555.do[O'Reilly].
Ce livre répartit un ensemble de conseils parmi quatre niveaux de composants:
Cette section se base sur deux ressources principales cite:[maintainable_software], qui répartit un ensemble de conseils parmi quatre niveaux de composants:
* Les méthodes et fonctions
* Les classes
* Les composants
* Et des conseils plus généraux.
Ces conseils sont valables pour n'importe quel langage.
Ces conseils sont valables pour n'importe quel langage.
==== Au niveau des méthodes et fonctions
@ -57,5 +49,3 @@ Ces conseils sont valables pour n'importe quel langage.
* *Conserver une densité de code faible*: il n'est évidemment pas possible d'implémenter n'importe quelle nouvelle fonctionnalité en moins de 20 lignes de code; l'idée ici est que la réécriture du projet ne prenne pas plus de 20 hommes/mois. Pour cela, il faut (activement) passer du temps à réduire la taille du code existant: soit en faisant du refactoring (intensif?), soit en utilisant des librairies existantes, soit en explosant un système existant en plusieurs sous-systèmes communiquant entre eux. Mais surtout, en évitant de copier/coller bêtement du code existant.
* *Automatiser les tests*, *ajouter un environnement d'intégration continue dès le début du projet* et *vérifier par des outils les points ci-dessus*.

View File

@ -7,3 +7,45 @@
year = {2018},
type = {Book}
}
@book{clean_code,
title = {Clean Code, a Handbook of Agile Software Craftmanship},
author = {Robert C. Martin},
publisher = {Pearson},
editor = {Addison-Wesley},
year = {2009},
type = {Book}
}
@book{expert_python,
title = {Expert Python Programming},
author = {Jaworski, Michal and Ziadé, Tarek},
publisher = {Packt Publishing},
year = {2021},
edition = {4th edition},
type = {Book}
}
@book{devops_handbook,
title = {The DevOps Handbook, How to create World-class Agility, Reliability, & Security in Technology Organizations},
author = {Gene Kim and Jez Humble and Patrick Debois and John Willis},
publisher = {IT Revolution},
year = {2016},
type = {Book}
}
@book{boring_stuff,
title = {Automate the Boring Stuff with Python},
booktitle = {Practical Programming For Total Beginners},
author = {Al Sweigart},
year = {2020},
editor = {No Starch Press},
publisher = {William Pollock},
edition = {2nd edition}
}
@book{maintainable_software,
title = {Building Maintainable Software},
booktitle = {Ten Guidelines for Future-Proof Code},
author = {Joost Visser},
year = {2016},
edition = {C# Edition, first edition},
publisher = {O'Reilly Media, Inc.},
isbn = {978-1-491-95452-2},
url = {http://shop.oreilly.com/product/0636920049555.do}
}