2017-04-13 17:08:27 +02:00
|
|
|
|
Introduction à la modularité
|
2017-03-17 11:58:08 +01:00
|
|
|
|
=============================
|
2017-03-17 11:33:14 +01:00
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Un langage de programmation doit permettre la programmation structurée.
|
|
|
|
|
|
|
|
|
|
.. important:: La structuration et l'organisation modulaire sert à maintenir de grands programmes,
|
|
|
|
|
Elles sont une nécessité
|
|
|
|
|
|
2017-03-17 11:33:14 +01:00
|
|
|
|
Structuration d'un programme
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
La réalisation d'applications importantes oblige le programmeur ou l'équipe de
|
|
|
|
|
développement à se poser des questions d'organisation et de structuration.
|
|
|
|
|
Aujourd'hui, on dispose de deux grands modèles d'organisation dont les avantages et les
|
|
|
|
|
particularités sont distincts.
|
|
|
|
|
|
2017-04-26 11:48:32 +02:00
|
|
|
|
L'écriture des vrais programmes consiste à les structurer pour les présenter
|
|
|
|
|
comme un assemblage de briques qui s'emboîtent naturellement.
|
|
|
|
|
Ce problème se révèle fondamental dès que la taille des programmes devient conséquente.
|
|
|
|
|
Si on ne prend pas garde au bon découpage des programmes en modules indépendants,
|
|
|
|
|
on se retrouve rapidement débordé par un grand nombre de variables,
|
|
|
|
|
et il devient quasiment impossible de réaliser un programme correct.
|
|
|
|
|
|
2017-03-17 11:33:14 +01:00
|
|
|
|
La modularité
|
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Les données et les traitements sont regroupés au sein d'une même entité à deux
|
|
|
|
|
facettes : d'un côté le code proprement dit, de l'autre son interface. La
|
|
|
|
|
communication entre modules s'effectue via leur interface. La description d'un
|
|
|
|
|
type peut être masquée en n'apparaissant pas dans l'interface du module. Ces
|
|
|
|
|
types de données abstraits facilitent les modifications d'implantation à
|
|
|
|
|
l'intérieur d'un module sans affecter les autres modules qui s'en servent. De
|
|
|
|
|
plus, les modules peuvent être paramétrés par d'autres modules augmentant
|
|
|
|
|
ainsi leur réutilisabilité.
|
|
|
|
|
|
|
|
|
|
Le paradigme objet
|
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Les descriptions des traitements et des données sont regroupées dans des
|
|
|
|
|
entités appelées **classes**; un objet est une instance (valeur) d'une classe.
|
|
|
|
|
La communication entre objets est réalisée par envoi de message, l'objet
|
|
|
|
|
receveur détermine à l'exécution (liaison retardée) le traitement
|
|
|
|
|
correspondant au message. En cela, la programmation objet est dirigée par
|
|
|
|
|
les données. La structuration d'un programme provient des relations entre
|
|
|
|
|
classes, en particulier l'héritage permet de définir une classe par extension
|
|
|
|
|
d'une autre.
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
En programmation objet, un **programme** est une collection d’objets qui communiquent
|
|
|
|
|
entre eux par **message**, le **résultat** est un message envoyé à un objet particulier
|
|
|
|
|
|
2017-03-17 11:33:14 +01:00
|
|
|
|
Comparaison entre les deux paradigmes
|
2017-03-17 11:58:08 +01:00
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2017-03-17 11:33:14 +01:00
|
|
|
|
|
|
|
|
|
Il y a dualité entre ces deux modèles.
|
|
|
|
|
|
|
|
|
|
- On ne peut pas augmenter les composants d'un type dans un module (pas
|
|
|
|
|
d'extensibilité des données), mais on peut ajouter de nouveaux traitements
|
|
|
|
|
(extensibilité des traitements) sur ces données.
|
|
|
|
|
|
|
|
|
|
- En objet, on peut ajouter des sous-classes à une classe (extensibilité des
|
|
|
|
|
données) pour traiter des nouveaux cas, mais on ne peut pas ajouter de nouveaux
|
|
|
|
|
traitements visibles de la classe ancêtre (pas d'extensibilité des traitements).
|
|
|
|
|
|
|
|
|
|
**La combinaison des deux paradigmes offre de nouvelles extensibilités pour les
|
|
|
|
|
traitements et les données.**
|
|
|
|
|
|
2017-04-13 17:08:27 +02:00
|
|
|
|
Sûreté d'exécution
|
|
|
|
|
--------------------
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
La programmation raisonnée
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Un **programme** est le codage d'un algorithme dans un langage de programmation.
|
|
|
|
|
La programmation consiste à modéliser un problème du monde réel sous une forme
|
|
|
|
|
symbolique (pour faire résoudre ce problème par un ordinateur).
|
|
|
|
|
|
|
|
|
|
Certains problèmes sont **indécidables** ou **ouverts**.
|
|
|
|
|
On utilise un langage de programmation pour décrire la **solution** du programme.
|
|
|
|
|
La sémantique du programme est le sens de chacune des constructions du langage.
|
|
|
|
|
**Comment passer de l'énoncé d'un problème à un programme de bonne qualité ?**
|
|
|
|
|
|
|
|
|
|
spécifier
|
|
|
|
|
|
|
|
|
|
décrire de manière complète et rigoureuse le problème à résoudre
|
|
|
|
|
|
|
|
|
|
modéliser
|
|
|
|
|
|
|
|
|
|
proposer une représentation du réel qui soit accessible au calcul
|
|
|
|
|
algorithmique
|
|
|
|
|
|
|
|
|
|
transcrire
|
|
|
|
|
|
|
|
|
|
La transcription du modèle algorithmique se fait dans un langage
|
|
|
|
|
de programmation cible adapté au problème
|
|
|
|
|
|
|
|
|
|
valider
|
|
|
|
|
|
|
|
|
|
La validation du programme est une étape qui permet de s'assurer plus ou
|
|
|
|
|
moins fortement que le programme produit les résultats attendus.
|
|
|
|
|
La validation va de la série de tests unitaires (validation faible)
|
|
|
|
|
à la preuve de programme (validation mathématique forte).
|
|
|
|
|
|
2017-03-18 07:00:18 +01:00
|
|
|
|
La preuve de programme
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Le niveau maximum de sûreté d'exécution d'un programme est la preuve. Qu'est-ce que la preuve
|
|
|
|
|
formelle d'un programme ? Selon la définition de Wikipédia, ce sont "des techniques permettant de
|
|
|
|
|
raisonner rigoureusement, à l'aide de logique mathématique, sur des programmes informatiques ou
|
|
|
|
|
du matériel électroniques, afin de démontrer leur validité par rapport à une certaine
|
|
|
|
|
spécification." Bref c'est un raisonnement logique sur un programmme qui permet d'être sûr que le
|
2017-03-18 07:00:18 +01:00
|
|
|
|
programme est valide et ne va pas planter.
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
La preuve de programme est très peu utilisée dans l'industrie, car très coûteuse et très
|
|
|
|
|
difficile à mettre en place. Elle quand même utilisée, mais dans des secteurs où le risque doit
|
|
|
|
|
absolument être évacué et où il n'y a aucun droit à l'erreur. Par exemple, le secteur médical
|
|
|
|
|
(informatique en bloc opératoire), militaire (peu d'informations nous parviennent dans ce
|
|
|
|
|
domaine), l'aviation civile (le logiciel Astrée pour Airbus), la fusée Ariane (depuis le bug qui
|
|
|
|
|
avait fait crasher Ariane 5 ces questions sont prises très au sérieux), et le milieu bancaire
|
|
|
|
|
(surtout le domaine des décisions boursières : un programme chargé de lancer des décisions
|
|
|
|
|
d'achat ou de vente à la bourse qui comporte un bug peut en quelque centièmes de secondes faire
|
|
|
|
|
perdre des millions, voire des milliards d'euros à une banque. Le programme ne doit tout simplement pas
|
2017-03-18 07:00:18 +01:00
|
|
|
|
bugger).
|
|
|
|
|
|
|
|
|
|
Le model checking
|
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Le model checking, l'analyse statique et l'interprétation abstraite procèdent d'une méthodologie
|
|
|
|
|
moins lourde de validation des programmes. Ces méthodes analysent exhaustivement l'évolution du
|
|
|
|
|
système lors de ses exécutions possibles et permetent de dire si globalement, dans un contexte
|
|
|
|
|
donné, le programme va fonctionner correctement. Encore très lourdes, ces techniques ne sont
|
2017-03-18 07:00:18 +01:00
|
|
|
|
utilisées que dans un contexte industriel de haute sécurité.
|
|
|
|
|
|
|
|
|
|
Les tests d'acceptation
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
Il y a plusieurs types de tests
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
- unitaires
|
|
|
|
|
- fonctionnels
|
|
|
|
|
- acceptation
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Très utilisés dans l'industrie, les tests unitaires et fonctionnels ne testent que certaines
|
|
|
|
|
parties du programme et permettent de dire que le programme va marcher grosso-modo à peu près.
|
2017-03-18 07:00:18 +01:00
|
|
|
|
Beaucoup moins coûteux à installer, ce sont des éléments cléfs des méthodes agiles.
|
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
Les Outils de linting (validation)
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
- vérifications syntaxiques
|
|
|
|
|
- vérification sémantiques
|
|
|
|
|
- vérification sur les imports inutiles ou mal formés (imports croisés
|
|
|
|
|
|
|
|
|
|
Exemple en python : pylint
|
|
|
|
|
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
La dette technique
|
2017-03-18 07:00:18 +01:00
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Au bout d'un moment le code devient du code spaghetti et les techniques sont obsolètes.
|
|
|
|
|
Les tests permettent de solder la dette technique plus facilement.
|
|
|
|
|
|
|
|
|
|
**avoir le courage de payer une dette technique, et affronter une dette technique
|
|
|
|
|
sinon il peut y avoir un coût à payer qui sera pohibitoire.**
|
|
|
|
|
|
|
|
|
|
On solde la dette technique parce que à un moment ça va devenir beaucoup trop
|
|
|
|
|
cher à payer.
|
|
|
|
|
|
2017-03-17 11:58:08 +01:00
|
|
|
|
Les méthodologies agiles
|
2017-03-18 07:00:18 +01:00
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
2017-03-17 11:58:08 +01:00
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
La manière dont le code est produit importe énormément. Par exemple, une
|
|
|
|
|
méthodologie ou le **refactoring** (réécriture de code) est permis et même conseillé
|
2017-03-17 11:58:08 +01:00
|
|
|
|
a plus de chance de produire du code organisé.
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Les méthodologies agiles produisent en général du code mieux organisé. Ce sont les
|
2017-03-17 11:58:08 +01:00
|
|
|
|
méthodes de travail les plus en vogue aujourd'hui, elles mettent l'accent sur :
|
|
|
|
|
|
|
|
|
|
- Du logiciel fonctionnel plutôt que de la documentation exhaustive
|
|
|
|
|
- La réponse au changement plutôt que le suivi d'un plan
|
|
|
|
|
- Le logiciel fonctionnel est la principale mesure d'avancement
|
2017-04-06 14:55:36 +02:00
|
|
|
|
- Une attention continue à l'excellence technique et à une bonne
|
2017-03-17 11:58:08 +01:00
|
|
|
|
conception améliore l'agilité
|
|
|
|
|
- La simplicité est essentielle (il est facile de faire, il est
|
|
|
|
|
difficile de faire simple)
|
|
|
|
|
|
2017-04-06 14:55:36 +02:00
|
|
|
|
Le principe de base de la méthodologie Scrum par exemple est de focaliser l'équipe de façon
|
|
|
|
|
itérative sur un ensemble de fonctionnalités à réaliser, dans des itérations de durée fixe de une
|
|
|
|
|
à quatre semaines, appelées **sprints**. Chaque sprint possède un but à atteindre, défini par le
|
|
|
|
|
responsable de produit, à partir duquel sont choisies les fonctionnalités à implémenter dans ce
|
|
|
|
|
sprint. Un sprint aboutit toujours sur la livraison d'un produit partiel fonctionnel. Pendant ce
|
|
|
|
|
temps, le facilitateur a la charge de réduire au maximum les perturbations extérieures et de
|
2017-03-18 07:00:18 +01:00
|
|
|
|
résoudre les problèmes non techniques de l'équipe.
|
|
|
|
|
|
2017-04-13 17:08:27 +02:00
|
|
|
|
Conception descendante
|
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
|
|
Une vision **centripète** : du général au particulier.
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
Il s'agit d'une méthode de résolution d'un problème. On le découpe en tâches
|
|
|
|
|
de plus en plus fines, de plus en plus détaillées, qui aboutiront au programme final.
|
2017-03-18 07:00:18 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
On met des *trous* dans les algorithmes de plus haut niveau,
|
|
|
|
|
c'est-à-dire des phrases en langage naturel.
|
2017-03-17 11:58:08 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
.. ifconfig: exercice
|
|
|
|
|
|
|
|
|
|
**Exercice** : **Calculer la date du lendemain**
|
|
|
|
|
|
|
|
|
|
.. ifconfig: correction
|
|
|
|
|
|
|
|
|
|
- l'algorithme de plus bas niveau
|
|
|
|
|
|
|
|
|
|
::
|
2017-03-17 11:58:08 +01:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
lendemain jour =
|
|
|
|
|
si jour [est le dernier jour du mois] alors
|
|
|
|
|
resultat = [calculer le 1er janvier de l'année suivante]
|
|
|
|
|
sinon
|
|
|
|
|
resultat = lendemain_dansl'année jour
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
- les algorithmes de plus bas niveau
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
::
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
lendemain_dans_l'année jour =
|
|
|
|
|
si jour [est le dernier jour du mois] alors
|
|
|
|
|
resultat = [calculer le premier jour du mois suivant]
|
|
|
|
|
sinon
|
|
|
|
|
resultat = jour suivant jour
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
::
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
jour_suivant jour =
|
|
|
|
|
jour + 1
|
2017-04-06 14:55:36 +02:00
|
|
|
|
|
2017-04-13 10:50:18 +02:00
|
|
|
|
et ainsi de suite jusqu'à ce que toutes les phrases soient calculables.
|
2017-04-18 21:53:35 +02:00
|
|
|
|
|
|
|
|
|
Algorithme vague
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
L'algorithme vague, c'est quand on pense l'algorithme en se plaçant du côté de
|
|
|
|
|
l'implémentation en premier. On a le nez dans le guidon, la vue d'ensemble est
|
|
|
|
|
difficile.
|
|
|
|
|
|
|
|
|
|
Voici, tiré du monde réel, un exemple d'algorithme vague
|
|
|
|
|
("ce que doit faire une fonction"), placé dans un bout de code
|
|
|
|
|
(souvent la **docstring** d'une fonction).
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
def upsert_route(*args, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Create or modify an existant DHCP route
|
|
|
|
|
param tuple (id or null, machine name, IP, MAC Adress)
|
|
|
|
|
return True or False with error message
|
|
|
|
|
"""
|
|
|
|
|
# si id présent alors modification sinon ajout
|
|
|
|
|
# récupère la liste des réservations en cours
|
|
|
|
|
# y cherche la variable sur la base de l'ID
|
|
|
|
|
# modifie les valeurs
|
|
|
|
|
# applique la nouvelle conf DHCP
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
Voici un autre bout de code avec l'algorithme en commentaire,
|
|
|
|
|
et l'implémentation effective de l'algorithme
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
def del_route(*args, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Delete an existant DHCP route
|
|
|
|
|
param tuple (id, machine name, IP, MAC Adress)
|
|
|
|
|
return True or False with error message
|
|
|
|
|
"""
|
|
|
|
|
# récupère la liste des réservations en cours
|
|
|
|
|
# y cherche la variable sur l'id donné en paramètre
|
|
|
|
|
# supprime l'entrée avec vérification que les données fournies
|
|
|
|
|
# sont bien dans l'enregistrement à supprimer
|
|
|
|
|
# applique la nouvelle conf DHCP
|
|
|
|
|
route_to_del = (1, "host2","10.1.2.4","6E:FF:56:A2:AF:17") # FIXME
|
|
|
|
|
routes = get_routes()
|
|
|
|
|
if route_to_del in routes:
|
|
|
|
|
c = creole_loader(load_extra=True, rw=True, owner=MODNAME, mandatory_permissive=False)
|
|
|
|
|
c_id = c.dhcp.dhcp.id_dhcp.id_dhcp.index(route_to_del[0])
|
|
|
|
|
if c.dhcp.dhcp.id_dhcp.macaddress[c_id]==route_to_del[2] and c.dhcp.dhcp.id_dhcp.ip[c_id]==route_to_del[1]:
|
|
|
|
|
c.dhcp.dhcp.id_dhcp.id_dhcp.pop(c_id)
|
|
|
|
|
config_save_values(c, MODNAME)
|
|
|
|
|
return True
|
|
|
|
|
return False
|