Introduction à la modularité ============================= 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é 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. 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. 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. 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 Comparaison entre les deux paradigmes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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.** Sûreté d'exécution -------------------- 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). Conception descendante ----------------------- Une vision **centripète** : du général au particulier. 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. On met des *trous* dans les algorithmes de plus haut niveau, c'est-à-dire des phrases en langage naturel. .. ifconfig: exercice **Exercice** : **Calculer la date du lendemain** .. ifconfig: correction - l'algorithme de plus bas niveau :: 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 - les algorithmes de plus bas niveau :: 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 :: jour_suivant jour = jour + 1 et ainsi de suite jusqu'à ce que toutes les phrases soient calculables. 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") routes = get_routes() if route_to_del in routes: c = creole_loader(load_extra=True, rw=True) 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