Spé. NSI · Terminale · cours rédigé et vérifié par Claryo, conforme au Bulletin officiel
La modularité consiste à découper un programme en unités indépendantes et réutilisables : fonctions, puis modules (fichiers), puis bibliothèques. Chaque unité a une responsabilité claire et unique. On gagne en lisibilité (un module se comprend isolément), en réutilisation (on réécrit moins de code), en maintenance (une correction reste localisée) et en testabilité (on teste chaque module séparément). C'est aussi indispensable au travail en équipe : plusieurs personnes peuvent développer des modules différents en parallèle.
La distinction centrale est celle entre interface et implémentation. L'interface décrit ce que fait un module : les noms de ses fonctions, leurs paramètres, leur type de retour, leur contrat. L'implémentation décrit comment il le fait : le code interne. Tant que l'interface reste stable, on peut remplacer l'implémentation par une version plus efficace sans modifier le code appelant. C'est le principe de la boîte noire, soutenu par l'encapsulation (cacher les détails internes).
Pour utiliser correctement un module, on rédige une spécification de chaque fonction : entrées (paramètres et types), sortie (résultat et type), préconditions. En Python, on assemble les modules avec import. import math rend disponible math.sqrt, tandis que from math import sqrt importe directement sqrt. Le bloc if __name__ == "__main__": permet de réserver le code de test ou le programme principal au lancement direct du fichier, sans le déclencher à l'import.
· import module -> appel module.fonction() ; from module import nom -> appel nom().
· Garde de script : if __name__ == "__main__": (exécuté seulement si lancé directement).
· Spécification : entrée(s) + type, sortie + type, préconditions.
Schéma : un programme principal qui importe trois modules (modele, validation, affichage), chacun n'exposant que son interface.
Pour découper un programme : lister les grandes responsabilités (données, validation, calcul, affichage) et créer un module par responsabilité. Pour chaque fonction publique, écrire d'abord sa spécification, puis son implémentation. Montrer un usage avec un import correct et un appel testable.
· Confondre interface (le contrat exposé) et implémentation (le code interne).
· from module import * pollue l'espace de noms et masque l'origine des noms : à éviter.
· Oublier que if __name__ == "__main__": n'est exécuté qu'au lancement direct.
· Un module qui fait « tout » casse la séparation des responsabilités : préférer plusieurs petits modules cohérents.
Savoir justifier la modularité par des avantages concrets, distinguer interface et implémentation, rédiger une spécification, et maîtriser les formes d'import en Python ainsi que le rôle de if __name__ == "__main__":. Pour l'épreuve pratique : importer et appeler proprement une fonction d'un autre fichier.