051.1 Leçon 1
Certification : |
Open Source Essentials |
---|---|
Version : |
1.0 |
Thème : |
051 Fondements des logiciels |
Objectif : |
051.1 Composants des logiciels |
Leçon : |
1 sur 1 |
Introduction
Les logiciels libres et à code source ouvert — souvent abrégés en FOSS (Free and Open-Source Software) — font désormais partie intégrante de notre vie quotidienne, la plupart du temps sans que nous en soyons conscients. Les FOSS, par exemple, se retrouvent sous une forme ou une autre derrière toutes nos activités sur l’internet : sur l’ordinateur sur lequel nous visualisons les pages web dans le navigateur, ou sur les serveurs qui stockent ces pages web et les livrent dès que nous les appelons.
Qu’est-ce qu’un logiciel ?
Toutefois, avant d’examiner toutes les spécificités des logiciels libres et à code source ouvert, il convient de préciser ce qu’est un logiciel. Commençons par une description très générale : Le logiciel est la partie non physique et immatérielle des ordinateurs, quelle que soit leur forme. Le logiciel garantit que les parties physiques (le matériel) de l’ordinateur interagissent et que l’ordinateur peut accepter des commandes et exécuter des tâches.
Un smartphone, un ordinateur portable ou un serveur dans un centre de données n’est qu’une machine faite de métal et de plastique lorsqu’il est éteint. Dès qu’il est allumé, un logiciel démarre, sous la forme de séquences de commandes codées qui contrôlent les différents composants de cette machine, qui permettent à l’utilisateur d’interagir avec la machine et qui exécutent des tâches très spécifiques en invoquant des applications individuelles.
C’est le travail des développeurs de logiciels d’analyser les tâches que l’ordinateur est censé accomplir et de les spécifier d’une manière qui permette à l’ordinateur de les mettre en œuvre. Les outils utilisés par les développeurs sont aussi nombreux et divers que les tâches accomplies par le logiciel.
Certaines tâches logicielles sont très étroitement liées au matériel et à l’architecture de l’ordinateur, par exemple l’adressage et la gestion de la mémoire ou la gestion de différents processus. Les programmeurs système travaillent donc à un niveau très proche du matériel.
Les développeurs d’applications, quant à eux, se concentrent davantage sur l’utilisateur et programment des applications qui permettent aux utilisateurs d’effectuer leurs tâches de manière efficace et intuitive. Un exemple d’application complexe est un programme de traitement de texte qui fournit toutes les fonctions de mise en forme du texte dans des menus ou des boutons et qui affiche également le texte tel qu’il pourrait être imprimé.
En général, un algorithme est une façon de résoudre un problème. Par exemple, pour calculer une moyenne, l’algorithme normal consiste à additionner une série de valeurs et à diviser la somme par le nombre total de valeurs. Bien que les algorithmes soient traditionnellement conçus et exécutés par des programmeurs, ils sont également générés de nos jours par l’intelligence artificielle.
Les concepts présentés dans ce chapitre peuvent vous aider à comprendre les avantages et les risques des logiciels libres, à faire des choix éclairés et même à décider si vous voulez devenir un développeur logiciel.
Langages de programmation
Les langages de programmation sont des langages artificiels hautement structurés qui indiquent à un ordinateur ce qu’il doit faire. Les programmes sont généralement écrits sous forme de texte, mais certains langages sont écrits sous forme graphique. Les développeurs logiciels écrivent des instructions (appelées code) à l’ordinateur dans ce langage artificiel. Cependant, le matériel de l’ordinateur n’exécute pas directement ce code. Le matériel ne peut exécuter directement qu’une suite de séquences de bits stockés dans la mémoire, appelée code machine ou langage machine. Tous les langages de programmation sont soit convertis en code machine par un compilateur, soit interprétés par un autre programme en code machine appelé interpréteur pour que le matériel exécute ces instructions.
Parmi les langages de programmation les plus utilisés actuellement figurent Python, JavaScript, C, C++, Java, C#, Swift et PHP. Chacun de ces langages de programmation a ses propres forces et faiblesses, et le choix du langage dépend du projet et des besoins du développeur. Par exemple, Java est un choix populaire pour le développement d’applications destinées aux très grandes entreprises, tandis que Python est souvent utilisé pour le calcul scientifique et l’analyse de données.
Les développeurs ont fait preuve d’une créativité impressionnante dans la conception des langages de programmation. À l’origine, il s’agissait de langages de bas niveau qui ressemblaient aux instructions de l’ordinateur. Les langages sont devenus de plus en plus de haut niveau, c’est-à-dire qu’ils tentent de représenter de puissantes combinaisons d’instructions en termes brefs. Certains langages reflètent la façon dont les gens pensent naturellement, tout en préservant la rigueur nécessaire pour fonctionner correctement.
Environ 400 langages de programmation sont actuellement connus, bien que nombre d’entre eux ne soient utilisés que dans des applications très spécifiques ou dans des anciens systèmes. Chacun d’entre eux a été développé pour résoudre certaines tâches.
Caractéristiques, syntaxe et structure des langages de programmation
Le choix du langage de programmation peut avoir un impact significatif sur les performances, l’extensibilité et la facilité de développement d’un projet logiciel. Ces sections présentent les éléments importants des langages.
Caractéristiques des langages de programmation
Parmi les caractéristiques et qualités communes des langages de programmation il y a :
- Concurrence
-
La concurrence désigne le traitement simultané de plusieurs tâches, soit en les exécutant sur différents processeurs matériels, soit en alternant l’utilisation d’un même processeur par les tâches. Le degré de concurrence pris en charge par un langage de programmation peut affecter considérablement ses performances et son extensibilité, en particulier pour les applications qui nécessitent un traitement en temps réel ou de grandes quantités de données. Chaque tâche distincte peut être appelée un processus, une tâche ou un thread.
- Gestion de la mémoire
-
La gestion de la mémoire est l’allocation et la libération de la mémoire dans un programme. En fonction du langage ou de l’environnement d’exécution, la gestion de la mémoire peut être effectuée manuellement par le programmeur ou gérée automatiquement. Une bonne gestion de la mémoire est essentielle pour garantir qu’un programme utilise efficacement la mémoire et qu’il n’en manque pas ou ne cause pas d’autres problèmes. Si un programme ne parvient pas à libérer la mémoire inutilisée, il provoque une fuite de mémoire qui augmente progressivement l’utilisation de la mémoire jusqu’à ce que le programme se bloque ou que des effets négatifs sur les performances soient perceptibles.
- Mémoire partagée
-
La mémoire partagée est un type de mécanisme de communication inter-processus qui permet à plusieurs processus de lire et de manipuler une région commune de la mémoire. La mémoire partagée est courante dans le matériel tel que les lecteurs de disques et peut également être un moyen efficace de partager des données entre les processus. Toutefois, ce mécanisme nécessite une synchronisation et une gestion minutieuse afin d’éviter la corruption des données. Une erreur connue sous le nom de course critique (race condition) se produit si un processus apporte une modification imprévue à des données alors qu’un autre processus les utilise.
- Transmission de messages
-
La transmission de messages est un mécanisme de communication entre processus qui leur permet d’échanger des données et de coordonner leurs activités. Il est couramment utilisé dans la programmation concurrente pour assurer la communication inter-processus et peut être mis en œuvre par divers mécanismes tels que les sockets, les tubes (pipes) ou les files d’attente de messages.
- Ramasse-miettes
-
Le ramasse-miettes (Garbage collection) est une technique de gestion automatique de la mémoire utilisée par certains langages de programmation pour récupérer la mémoire qui n’est plus utilisée pendant l’exécution d’un processus. Cette technique permet d’éviter les fuites de mémoire et facilite l’écriture d’un code correct et efficace par les développeurs, mais elle peut également introduire des surcoûts de performance et rendre plus difficile le contrôle du comportement précis du programme.
- Types de données
-
Les types de données déterminent le type d’informations qui peuvent être représentées dans le programme. Les types de données peuvent être prédéfinis dans le langage ou définis par l’utilisateur, et peuvent inclure des nombres entiers, des nombres à virgule flottante (c’est-à-dire des approximations de nombres réels), des chaînes de caractères, des tableaux et d’autres.
- Entrée et sortie (E/S)
-
Les entrées et les sorties sont des mécanismes permettant de lire et d’écrire des données vers et depuis un programme. Les entrées peuvent provenir de diverses sources, telles que les clics de l’utilisateur et les saisies au clavier, un fichier ou une connexion réseau, tandis que les sorties peuvent être envoyées vers diverses destinations, telles qu’un écran, un fichier ou une connexion réseau. Les E/S permettent aux programmes d’interagir avec le monde extérieur et d’échanger des informations avec d’autres systèmes.
- Gestion des erreurs
-
La gestion des erreurs détecte et répond aux erreurs qui se produisent pendant l’exécution d’un programme. Il s’agit notamment d’erreurs telles que la division par zéro ou le fait qu’un fichier demandé soit introuvable. La gestion des erreurs permet aux programmes de continuer à fonctionner même lorsque des erreurs se produisent, améliorant ainsi leur fiabilité et leur robustesse.
Les concepts énumérés ci-dessus sont fondamentaux pour comprendre le fonctionnement des langages de programmation et la manière d’écrire un code efficace et facile à maintenir.
Syntaxe des langages de programmation
La syntaxe d’un langage de programmation fait référence aux règles d’écriture des déclarations et des expressions du programme. Il est important que la syntaxe soit bien définie et consistante, afin que le programmeur puisse écrire et comprendre efficacement son code. Les éléments suivants sont les composantes de base de la plupart des langages de programmation :
- Procédures et fonctions
-
Les procédures et les fonctions sont utilisées pour définir des blocs de code réutilisables qui peuvent être appelés plusieurs fois.
- Variables
-
Les variables représentent des morceaux de mémoire et stockent des données qui peuvent être manipulées et transmises entre les procédures et les fonctions.
- Opérateurs
-
Les opérateurs sont des mots-clés ou des symboles (tels que
+
et-
) qui attribuent des valeurs aux variables et effectuent des opérations arithmétiques. - Structure de contrôle
-
En général, le code du programme est exécuté dans l’ordre dans lequel il est écrit, mais les instructions conditionnelles modifient le flux d’exécution. Le code qui est exécuté ensuite dépend de diverses conditions, telles que le contenu de la mémoire, l’état du clavier, les paquets arrivant du réseau, etc. Les instructions itératives, une forme spéciale d’instructions conditionnelles, sont utiles pour effectuer les mêmes opérations sur une série d’ensembles de données. Une exception, qui invoque un code spécial en cas d’erreur, est une autre structure de contrôle.
La syntaxe et le comportement de ces constructions peuvent varier d’un langage de programmation à un autre, et le choix du langage peut avoir un impact important sur la lisibilité et la facilité de maintenance du code.
Bibliothèques
Un bon langage de programmation doit permettre de développer facilement des programmes et de réutiliser facilement le code existant. De nombreux langages de programmation disposent d’un mécanisme permettant d’organiser les procédures et les fonctions en parties réutilisables dans d’autres programmes.
Une bibliothèque est un ensemble de procédures et de fonctions destinées à supporter une caractéristique ou un objectif particulier, regroupées dans un seul fichier. La disponibilité de nombreuses bibliothèques faciles à utiliser est une autre exigence très importante d’un bon langage de programmation. Par exemple, Python est largement reconnu comme un bon langage pour développer des programmes liés à l’intelligence artificielle, car il dispose d’un certain nombre de bibliothèques adaptées au traitement par l’intelligence artificielle.
Avec l’augmentation de la taille et de la complexité des programmes, les bibliothèques en tant que blocs de construction prêts à l’emploi deviennent de plus en plus importantes. C’est particulièrement vrai dans le monde de l’open source, où les utilisateurs sont à l’aise avec le code créé par d’autres et le réutilisent. En conséquence, un écosystème de bibliothèques s’est développé pour chaque langage de programmation, et les gestionnaires de paquets tels que composer
pour PHP, pip
pour Python, et gems
pour Ruby facilitent l’installation des bibliothèques.
Les bibliothèques sont également importantes dans les langages compilés. La combinaison de plusieurs fichiers binaires et de bibliothèques pré-compilées pour obtenir un seul fichier exécutable est appelée édition de liens, et l’outil qui effectue cette opération est appelé éditeur de liens. Il existe deux types d’édition de liens : la liaison statique, dans laquelle seul le code de la bibliothèque nécessaire est inclus dans le fichier exécutable de l’application finale et la liaison dynamique, dans laquelle une bibliothèque installée dans le système est partagée par toutes les applications qui utilisent cette bibliothèque. Actuellement, la liaison dynamique est l’approche préférée et se caractérise par des exécutables d’application plus petits et une utilisation moindre de la mémoire au moment de l’exécution.
Notez que, comme les mêmes bibliothèques peuvent être utilisées par plusieurs programmes, les différences entre les versions d’une bibliothèque peuvent être encore plus problématiques que pour les applications. Faisons une parenthèse et rappelons-nous comment regarder les numéros de version. La gestion sémantique de version (semantic versioning) est couramment utilisée, qui indique les versions par trois nombres séparés par des points. Une version typique peut-être 2.39.16
, qui indique une version majeure de 2 (un nombre qui ne changera probablement qu’une fois toutes les quelques années), une version mineure de 39 dans la version majeure (qui peut être mise à jour tous les quelques mois pour contenir des changements de fonctionnalités importants), et une révision rapide de 16 (qui peut changer à cause d’une seule correction de bogue). Les versions et révisions ultérieures ont des numéros plus élevés.
Un exemple très simple
Examinons un exemple très simple de programme informatique en langage Python pour avoir une idée sommaire de quelques-uns des éléments mentionnés.
Exprimé en langage naturel, le programme est censé faire ce qui suit : « Demander à l’utilisateur d’entrer un nombre et vérifier si ce nombre est pair ou impair. Enfin, affichez le résultat. »
Et voici le code que nous pouvons sauvegarder dans le fichier simpleprogram.py
:
num = int(input("Enter a number: "))
if (num % 2) == 0:
print("The given number is EVEN.")
else:
print("The given number is ODD.")
Même dans ces quelques lignes de code, on retrouve un grand nombre des caractéristiques et des éléments de syntaxe mentionnés ci-dessus :
-
À la ligne 1, nous définissons la variable
num
et lui assignons une valeur avec l'_opérateur=
. -
La valeur attribuée correspond à l'entrée de l’utilisateur (via la fonction
input()
). En outre, la fonctionint()
veille à ce que cette entrée soit convertie, si c’est possible, en un type de données entier. L’expression passée à une fonction entre parenthèses est appelée paramètre ou argument. -
Si l’utilisateur entre une chaîne de caractères, Python affichera une erreur dans le cadre de sa gestion des erreurs. Si un nombre décimal est saisi, la fonction
int()
le convertit en un nombre entier, par exemple5.73
en5
. -
Dans les lignes suivantes, la structure de contrôle énonçant une condition, avec les mots-clés
if
etelse
, contrôle ce qui se passe dans chacun des deux cas possibles (le nombre est soit pair, soit impair). -
Tout d’abord, l’opérateur modulo
%
teste si (if
) la division du nombre saisi par 2 donne la valeur 0 (c’est-à-dire pas de reste) — dans ce cas, le nombre est pair. L’opérateur doublé==
est l’opérateur de comparaison « est égal à », qui est différent de l’opérateur d’affectation=
de la ligne 1. -
Dans l’autre cas (
else
), c’est-à-dire lorsque la division par 2 donne un résultat différent de 0, le nombre saisi doit être impair. -
Dans les deux cas, la fonction
print()
renvoie le résultat en tant que sortie sous forme textuelle.
Et voici à quoi cela ressemble lorsque nous exécutons le programme sur la ligne de commande :
$ python simpleprogram.py Enter a number: 5 The given number is ODD.
Lorsque vous considérez la quantité de logique du langage déjà présente dans ce petit exemple, vous pouvez vous faire une idée de ce dont sont capables les logiciels complexes distribués sur des milliers de fichiers ; par exemple, les systèmes d’exploitation tels que Microsoft Windows, macOS ou Linux, qui rendent tout le matériel d’un ordinateur disponible et garantissent en même temps que les utilisateurs peuvent installer toutes les autres applications souhaitées et les utiliser pour le travail ou pour le plaisir.
Code machine, langage d’assemblage et assembleurs
Comme indiqué précédemment, le matériel ne peut exécuter directement qu’une suite de séquences de bits appelées code machine. Le processeur (CPU) lit une séquence de bits de la mémoire en unités d’un mot (8 à 64 bits) et exécute l’instruction correspondante. Les instructions individuelles sont assez simples, par exemple « copier le contenu de l’emplacement mémoire A vers l’emplacement mémoire B », « multiplier le contenu de l’emplacement mémoire C par le contenu de l’emplacement mémoire D » ou « lire les données qui sont arrivées au périphérique à l’adresse X ». De nos jours, le nombre de modèles d’instructions a augmenté de façon exponentielle et il n’est plus possible de se souvenir de tous ces modèles.
Le code machine est une suite de séquences de bits, ou des 0 et des 1, ce qui n’est pas du tout intuitif pour les êtres humains. Pour rendre la programmation plus intuitive, le langage d’assemblage a été créé, dans lequel les instructions reçoivent des noms et peuvent être spécifiées par des chaînes de caractères. Dans le langage d’assemblage, les instructions qui correspondent une à une au code machine sont écrites une à la fois. Les instructions peuvent ressembler à ce qui suit :
move [B], [A] copier le contenu de la mémoire A vers la mémoire B multi R1, [C], [D] multiplier le contenu de la mémoire C par celui de la mémoire D input R1, [X] lire les données qui sont arrivées au périphérique à l'adresse X
Une instruction en langage d’assemblage correspond à une instruction en code machine, qui correspond à l’instruction exacte que le matériel peut comprendre et exécuter. Les avantages du langage d’assemblage par rapport au langage machine sont les suivants :
- Amélioration de la lisibilité et de la maintenabilité
-
Le langage d’assemblage est beaucoup plus facile à lire et à écrire que le code machine. Il est donc plus simple pour les programmeurs de comprendre, de déboguer et de maintenir leur code.
- Automatisation du calcul des adresses
-
La programmation en code machine peut également utiliser le concept de variables et de fonctions, mais tout doit être exprimé en termes d'adresses mémoire. Le langage d’assemblage attribue aussi des noms aux adresses mémoire, ce qui facilite la formulation de la logique d’un programme.
Puisque le langage d’assemblage a accès à toutes les fonctionnalités du matériel, il est couramment utilisé dans les situations suivantes :
- Partie du système d’exploitation qui dépend de l’architecture
-
L’utilisation d’instructions spécifiques à une architecture de processeur, pour l’accès aux fonctions d’initialisation et de sécurité, ne peut se faire qu’en langage d’assemblage.
- Développement de composants système de bas niveau
-
Le langage d’assemblage est utilisé pour développer les composants du système qui doivent interagir directement avec le matériel de l’ordinateur, tels que les pilotes de périphériques, les micrologiciels (firmware) et le système élémentaire d’entrée/sortie (BIOS - Basic Input/Output System). En particulier, les dispositifs à grande vitesse qui nécessitent de pousser les performances matérielles à leurs limites ont souvent besoin de pilotes et de micrologiciels programmés en langage d’assemblage.
- Programmation des microcontrôleurs
-
Le langage d’assemblage est également utilisé pour programmer les microcontrôleurs, qui sont de petits ordinateurs de faible puissance utilisés dans un large éventail de systèmes intégrés, des jouets au contrôle industriel. Certains microcontrôleurs ont une capacité de mémoire de quelques centaines d’octets seulement et sont généralement programmés en langage d’assemblage.
Le code du langage d’assemblage est converti en code machine avant d’être exécuté par une application appelée assembleur. L’assembleur est le plus ancien outil de programmation et a apporté un certain nombre d’avantages qui étaient impensables dans la programmation en code machine. Pour brouiller les pistes, le langage d’assemblage est parfois appelé assembleur.
Le code machine et le langage d’assemblage diffèrent d’un processeur à un autre. Ils sont appelés « langages de bas niveau » parce qu’ils opèrent directement sur le matériel. Cependant, les concepts de calcul et d’entrée/sortie sont les mêmes pour tous les processeurs. Si les concepts communs peuvent être exprimés d’une manière plus facile à comprendre pour les êtres humains, l’efficacité de la programmation peut être considérablement améliorée. C’est là qu’interviennent les « langages de haut niveau ».
Langages compilés
Les langages compilés sont des langages de programmation qui sont traduits soit en code machine, soit dans un format intermédiaire appelé bytecode (code à octets). Le bytecode est exécuté sur l’ordinateur cible par une machine virtuelle d’exécution. La machine virtuelle traduit le bytecode en code machine adapté à chaque ordinateur. Le bytecode permet aux programmes d’être indépendants de la plate-forme et de fonctionner sur n’importe quel système doté d’une machine virtuelle compatible.
La traduction du code source écrit dans un langage de programmation de haut niveau en code machine ou en bytecode est effectuée par un compilateur. Parmi les exemples de langages compilés qui produisent directement du code machine, on peut citer C et C++. Les langages qui produisent du bytecode incluent Java et C#.
Le choix entre le code machine et le bytecode dépend des exigences du projet, telles que la performance, la neutralité par rapport à la plate-forme et la facilité de développement.
Langages interprétés
Les langages interprétés sont des langages de programmation qui sont exécutés par un interpréteur, plutôt que d’être compilés en code machine. L’interpréteur lit le code source et exécute les instructions qu’il contient. Un interpréteur est capable de traiter directement le code source, sans le transformer dans un autre format de fichier. Ainsi, contrairement à un compilateur, qui traduit l’ensemble du programme en code machine avant de l’exécuter, un interpréteur lit chaque ligne de code et l’exécute immédiatement, ce qui permet au programmeur de voir les résultats de chaque ligne au fur et à mesure qu’elle est exécutée.
Les langages interprétés sont couramment utilisés pour écrire des scripts, c’est-à-dire des programmes courts qui automatisent des tâches, pour les interfaces en ligne de commande et pour le contrôle des lots et des travaux. Les scripts écrits dans des langages interprétés peuvent être facilement modifiés et exécutés sans nécessiter une recompilation, ce qui les rend bien adaptés aux tâches qui nécessitent un prototypage rapide ou une itération souple et rapide. Cette commodité s’accompagne de quelques inconvénients potentiels. Par exemple, un programme interprété s’exécute plus lentement que son équivalent compilé.
Python, Ruby et JavaScript sont des exemples de langages interprétés. Python est largement utilisé dans l’informatique scientifique, l’analyse de données et l’apprentissage automatique, tandis que Ruby est souvent utilisé dans le développement web et pour créer des scripts d’automatisation. JavaScript est un langage de script côté client intégré dans les navigateurs web pour créer des pages web dynamiques et interactives.
Langages orientés données
Les langages orientés données sont des langages de programmation optimisés pour le traitement et la manipulation de grandes quantités de données. Ils sont conçus pour traiter efficacement de grands ensembles de données structurées ou non structurées et fournissent un ensemble d’outils pour travailler avec des bases de données, des structures de données et des algorithmes pour le traitement et l’analyse des données.
Les langages orientés données sont utilisés dans une variété d’applications, y compris les sciences des données, l’analyse des données massives (big data), l’apprentissage automatique (machine learning) et la programmation des bases de données. Ils sont bien adaptés aux tâches qui impliquent le traitement et l’analyse de grandes quantités de données, telles que le nettoyage et la transformation des données, la visualisation des données et la modélisation statistique.
Parmi les exemples de langages orientés données, il y a SQL (abréviation de Structured Query Language ou langage de requêtes structurées), R et MATLAB. SQL est un langage standard utilisé pour gérer les bases de données relationnelles et il est largement utilisé dans les entreprises et l’industrie. R est un langage de programmation et un environnement pour le calcul statistique et les graphiques. Il est largement utilisé dans la science des données et l’apprentissage automatique. MATLAB est un environnement de calcul numérique et un langage de programmation utilisé dans un large éventail d’applications, notamment le traitement des signaux, le traitement des images et la finance informatisée.
Paradigmes de programmation
Outre les spécificités des langages de programmation, les paradigmes de programmation déterminent l’approche particulière à adopter pour trouver une solution. Nous pouvons considérer un paradigme comme une stratégie de base avec laquelle nous abordons une tâche, en fonction des exigences et des conditions spécifiques.
Un exemple comparable est la construction d’une maison : Que les maçons montent les murs brique par brique ou que les éléments en béton préfabriqués soient assemblés sur place est une décision fondamentale qui dépend des exigences et des circonstances. Quelles sont les caractéristiques souhaitées pour la maison ? Où est-elle située ? Est-elle reliée à d’autres maisons ?
De même, les paradigmes définissent l’orientation de la programmation : comment et de quelle manière, par exemple, un projet logiciel est divisé en parties plus petites et distinctes. Chaque langage de programmation convient mieux à un paradigme particulier. Le choix du paradigme est donc étroitement lié au choix du langage de programmation.
Les paradigmes suivants sont répandus dans la programmation :
- Programmation orientée objet (POO)
-
La POO est basée sur le concept d'objets, qui sont des instances de classes qui encapsulent les données et le comportement. Par exemple, un langage peut proposer un rectangle comme classe pour aider le programmeur à afficher une boîte à l’écran.
La POO se concentre sur la manipulation des données au niveau de l’objet. La POO facilite l’écriture d’un code qui est maintenable, réutilisable et extensible. Elle est largement utilisée dans les logiciels de bureau, les jeux vidéo et les applications web. Java, C# et Python sont des exemples de langages de programmation orientés objet.
- Programmation procédurale
-
La programmation procédurale exécute des tâches via des procédures, ou des blocs de code qui peuvent être exécutés dans un ordre spécifique. Cela permet d’écrire un code structuré, facile à suivre, mais peut conduire à un code moins flexible et plus difficile à maintenir à mesure que la taille et la complexité du projet augmentent. Le C, le Pascal et le Fortran sont des exemples de langages de programmation procéduraux.
D’autres approches du développement de logiciels sont utilisées aujourd’hui, pour lesquelles certains langages sont mieux adaptés que d’autres. En outre, les interfaces glisser-déposer (drag-and-drop) permettent aux non-programmeurs d’écrire des programmes, et de nombreux services en ligne ont récemment commencé à générer du code grâce à l’intelligence artificielle lorsqu’on leur donne un texte en langage courant.
En conclusion, chaque paradigme de programmation a ses propres forces et faiblesses, et le choix du paradigme dépend souvent des besoins du projet, de l’expérience et des préférences du développeur, ainsi que des contraintes de la plateforme et de l’environnement de développement. Comprendre les différents types de paradigmes peut vous aider à choisir le bon paradigme pour vos besoins, et peut également vous aider à écrire un code meilleur et plus efficace.
Exercices guidés
-
Quel est l’objectif des fonctions ?
-
Quel est l’avantage du bytecode par rapport à un fichier de code machine ?
-
Quel est l’avantage d’un fichier en code machine comparé à un fichier en bytecode ?
Exercices d’exploration
-
Quels sont les inconvénients de la décomposition d’un programme en un grand nombre de processus ou de tâches ?
-
Vous avez trouvé plusieurs paquets open source, proposés dans différentes versions, qui offrent les fonctionnalités dont vous avez besoin pour votre programme. Quels sont les critères de choix d’un paquet ?
-
Outre les paradigmes de développement POO et procédural, quelles sont les autres approches de développement logiciel existantes et quel est le langage de programmation le mieux adapté à chacune d’entre elles ?
Résumé
Dans cette leçon, vous avez appris ce qu’est un logiciel et comment il est développé à l’aide de langages de programmation. Les nombreux langages de programmation se distinguent non seulement par leur syntaxe, mais aussi, par exemple, par leur gestion des ressources matérielles ou des structures de données.
Les langages de programmation diffèrent également par la manière dont le code source, lisible par les êtres humains, est converti par un interpréteur ou un compilateur en code machine final à exécuter par l’ordinateur.
Les paradigmes de programmation déterminent la stratégie des projets logiciels et donc le choix des langages de programmation appropriés, en fonction des exigences et de la taille du projet concerné.
Réponses aux exercices guidés
-
Quel est l’objectif des fonctions ?
Les fonctions encapsulent certaines activités courantes, telles que l’édition d’une chaîne de caractères. En créant une fonction, vous permettez à votre programme et à d’autres programmes d’exécuter la fonction de manière pratique et répétée sans avoir à écrire leur propre code.
-
Quel est l’avantage du bytecode par rapport à un fichier de code machine ?
Le fichier bytecode peut être exécuté sur de nombreux ordinateurs différents, où une machine virtuelle transforme le code en code machine. Par exemple, JavaScript fonctionne dans de nombreux navigateurs sur de nombreux types d’ordinateurs.
-
Quel est l’avantage d’un fichier en code machine comparé à un fichier en bytecode ?
Le code machine s’exécute le plus rapidement que possible. Le bytecode s’exécute plus lentement, car la machine virtuelle doit le transformer en code machine pendant son exécution.
Réponses aux exercices d’exploration
-
Quels sont les inconvénients de la décomposition d’un programme en un grand nombre de processus ou de tâches ?
Lorsqu’un programme est décomposé en processus, ceux-ci doivent communiquer entre eux. S’ils travaillent sur un grand nombre de données communes, les processus risquent de dépenser beaucoup de ressources pour l’échange de données et la protection des données contre des modifications multiples et simultanées (course critique). Les processus entraînent également des surcharges lorsqu’ils démarrent et se terminent. Plus il y a de processus, plus le programme et ses interactions deviennent complexes, de sorte que les erreurs peuvent être plus difficiles à trouver.
Le paradigme fonctionnel tend à faciliter la décomposition des programmes en de nombreux processus, en raison de l’immuabilité. Les données immuables ne souffrent pas de conditions de course.
-
Vous avez trouvé plusieurs paquets open source, proposés dans différentes versions, qui offrent les fonctionnalités dont vous avez besoin pour votre programme. Quels sont les critères de choix d’un paquet ?
Vérifiez les rapports de bogues et les avis de sécurité concernant les paquets, car certains sont très bogués, voire dangereux. Parfois, la dernière version n’est pas la meilleure, parce qu’une faille de sécurité peut y avoir été introduite.
Consultez le forum sur lequel les développeurs parlent du paquet, pour vérifier qu’il est activement maintenu. Votre programme sera probablement utilisé pendant longtemps, et vous voulez que le paquet soit également disponible et robuste au fil du temps.
Essayez différents paquets pour vérifier leurs performances et leur exactitude.
La plupart des paquets dépendent de fonctions trouvées dans d’autres paquets (dépendances), de sorte qu’une faiblesse dans l’une des dépendances peut affecter votre programme.
-
Outre les paradigmes de développement POO et procédural, quelles sont les autres approches de développement logiciel existantes et quel est le langage de programmation le mieux adapté à chacune d’entre elles ?
Outre les paradigmes de développement POO et procédural, les autres types de paradigmes sont les suivants.
La programmation fonctionnelle met l’accent sur l’utilisation de fonctions et de concepts mathématiques, tels que les lambdas et les clôtures (closures), pour écrire un code basé sur l’évaluation d’expressions plutôt que sur l’exécution de déclarations. La programmation fonctionnelle traite les fonctions comme des citoyens de première classe — de sorte qu’elles peuvent être manipulées par le programme — et met l’accent sur l'immuabilité, ou le fait de travailler avec des variables qui ne peuvent pas changer après avoir été initialement définies. Cela facilite le raisonnement et le test du code, ainsi que l’écriture d’applications concurrentes et parallèles. Erlang, Haskell, Lisp et Scheme sont des exemples de langages de programmation fonctionnels.
Les langages impératifs se concentrent sur les déclarations nécessaires pour contrôler le flux des transitions du programme depuis et vers différents états.
Les langages déclaratifs décrivent les actions à entreprendre et la logique qui se cache derrière les instructions. L’ordre dans lequel les instructions sont exécutées n’est pas spécifié. Ces instructions, appels de fonctions et autres déclarations peuvent être réorganisés et optimisés par les compilateurs tant qu’ils préservent la logique sous-jacente.
La programmation naturelle est un paradigme de programmation qui utilise le langage naturel ou d’autres représentations adaptées à un être humain pour décrire le comportement souhaité d’un programme. L’idée est de rendre la programmation accessible aux personnes qui n’ont pas de formation théorique en informatique. Scratch et Alice sont des exemples de langages de programmation naturelle.