8 Concepts de la Programmation Orientée Objet
8.1 Les paradigmes de programmation
Il s’agit des différentes façons de raisonner et d’implémenter une solution à un problème en programmation. Nous pouvons citer trois grandes familles :
- La programmation impérative
paradigme originel et le plus courant - La programmation orientée objet (POO)
consistant en la définition et l’assemblage de briques logiciel appelées objets - La programmation déclarative
consistant à déclarer les données du problème, puis à demander au programme de le résoudre
8.2 Le concept d’objet
Le problème à traiter va être modélisé par des objets. Un objet est une entité caractérisée par :
- Un état, représenté par des données spécifiques à l’objet que nous appellerons des attributs.
- Des comportements, représentés par des fonctions spécifiques au type d’objet que nous appelleront des méthodes.
Un objet est donc un composant qui regroupe au sein d’une même entité des données et des traitements.
Vous avez déjà manipulé des objets. Si nous prenons les listes, l’état correspond aux données de la liste et les comportements sont les méthodes comme sort, split, append…
Un objet sera un composant du traitement de notre problème et plusieurs objets devront interagir pour traiter notre problème. Un principe pour la conception des objets est que chaque objet devra avoir une seule responsabilité. Par exemple, un objet qui gérera un compte ne s’occupera pas de son affichage.
8.3 La notion de classe
En programmation orientée objet, nous utilisons des objets. La structure de ces objets est définie dans des classes. Une classe peut être vue comme le moule qui permet de produire les objets. Dans le vocabulaire orienté objet, les objets sont des instances d’une classe. Les objets étant en soi des données, ils ont un type qui est leur classe.
Bien qu’un objet soit l’instance d’une classe, nous allons voir qu’il s’agit de deux composants différents dans le mécanisme de la programmation orientée objet.
8.4 Représentation : présentation d’UML
Afin de pouvoir représenter les notions de classes et objets, nous allons utiliser UML, Unified Modeling Language. UML est un langage de modélisation graphique basé sur des diagrammes et des pictogrammes. Il est standardisé et se veut être une synthèse des méthodes de modélisation. Pour cela, en version 2.5, il propose 14 type de diagrammes qui vont bien au delà de la modélisation objet.
8.4.1 Représenter une classe
La classe la plus basique peut être représentée par le diagramme ci-dessous. Cette classe n’a ni état (pas d’attributs) ni de comportement (pas de méthode). Notez que le nom de la classe correspond à la règle de nommage de la PEP8 et est donc en CamelCase.
Si cette classe n’est pas censée exister d’un point de vue paradigme, elle nous permet de voir le code qui permet de déclarer une classe dans la partie suivante.
8.4.2 Représenter les attributs et méthodes
Pour illustrer le concept de l’orienté objet, nous utiliserons un exemple de suivi de formations. Nous allons commencer par définir ce qu’est une formation et les actions sur celle-ci.
L’état d’une formation est représentée par son nom, sa durée, le nombre de places et la liste des stagiaires (pour l’instant représentés par leur nom). Une formation a donc les attributs subject, duration, students et available_seats.
À une formation, nous pouvons ajouter ou supprimer des participants, nous aurons donc des méthodes pour cela.
UML permet de représenter dans un diagramme de classe ses attributs et méthodes. Le diagramme ci-dessous représente cette notion de formation.
Une classe est représentée en 3 blocs. Le premier est le nom de la classe, le second est l’ensemble des attributs de la classe et la troisième les méthodes.
Pour les attributs, il est possible de spécifier le type et la valeur par défaut.
Les méthodes spécifient les paramètres attendus entre parenthèses ainsi que le type du retour.
Attributs et méthodes sont précédés d’un symbole qui représente leur visibilité.
Trainingest le nom de la classe.title,duration,studentsetseatssont des attributs.add_student(name),remove_student(name)etstudents()sont des méthodes.
8.4.3 Notion de visibilité des attributs et méthodes
La visibilité est un concept important de la conception objet puisqu’elle définit qui pourra accéder à l’attribut ou à la méthode et permet de mettre en œuvre le principe de l’encapsulation. Accéder à un attribut signifie avoir la possibilité de consulter la valeur mais aussi la modifier. UML permet de représenter 4 visibilité :
- Public représenté par le symbole
+. Un attribut ou une méthode publique pourra être accédé par n’importe quel composant. - Package représenté par le symbole
~. Un attribut ou une méthode package pourra être accédé par n’importe quel composant déclaré dans le même package. - Protected représenté par le symbole
#. Un attribut ou une méthode protégée ne pourra être accédé que par le composant qui l’a déclaré ou par tout composant spécialisé (voir notions d’héritage) - Private représenté par le symbole
-. Un attribut ou une méthode privée ne pourra être accédé que par le composant qui l’a déclaré.
Dans notre exemple, la durée, la liste des participants et le nombre de places disponibles sont des attributs privés car ils ne doivent pas être modifiés par un composant extérieur. La liste de participants évoluera par appel aux méthodes d’ajout et suppression de participants. Des méthodes permettent également de consulter ces attributs privés (students() et duration()).
Vous avez remarqué que ce modèle ne permet pas en l’état de consulter le nombre de places disponibles.
8.4.4 Cardinalité et contraintes
La liste des stagiaires est définie comme pouvant contenir de 0 à un nombre indéfini de stagiaires. Mais une formation a une limite de places. Cette limite dépend de la formation. Il est donc impossible de l’imposer dans le modèle, ce qui nous conduit à cette cardinalité de 0 ou plusieurs.
UML ne permet pas de modéliser les contraintes, celles-ci sont modélisées par un autre langage, OCL (Object Constraint Language). Cette contrainte doit être appliquée à notre modèle et c’est pourquoi l’ajout de participants doit passer par une méthode. Celle-ci connait la règle métier qui sera d’ajouter un stagiaire uniquement si le nombre de participants est inférieur au nombre de places.
8.4.5 La notion de relations
Lorsque nous définissons des objets, ceux-ci peuvent être liés les uns aux autres. Nous parlons de relations.
Les relations permettent de représenter les associations entre les classes.
Nous pouvons compléter notre modèle de formation. Un stagiaire n’est pas limité à une chaine de caractères, nous pouvons définir une classe pour le représenter. Il faudra ensuite l’associer à la formation.
8.4.6 Relation simple
En UML, la relation est symbolisée par un trait, en général horizontal, reliant les deux classes. Une flèche permet d’orienter la relation. Cette dernière est importante car elle détermine où (dans quelle classe) sera exprimée la relation.
UML nous permet également de préciser la cardinalité de cette relation. Les indications possibles sont :
noù n est un nombre signifiant exactement n instances*signifie un nombre indéterminé d’instancesm..noù m est un entier et n est soit un entier soit*et signifie demàninstances.
Dans notre modèle, une formation est dispensée à plusieurs stagiaires et un même stagiaire peut suivre plusieurs formations.
La flèche ainsi que la définition de la relation indiquée au dessus de cette flèche nous renseigne sur l’implémentation attendue. Ainsi, une formation possède des stagiaires. L’implémentation devra donc définir une liste de stagiaires dans la classe Training. Vous remarquerez qu’il n’y a pas d’attribut students:Student[*] déclarée dans ce dernier schéma, contrairement au premier. C’est parce cette relation implique implicitement cet attribut.
8.5 UML : les limites de la représentation graphique
Nous avons vu que nous pouvons représenter beaucoup d’informations sous forme de diagrammes en UML. Mais la représentation graphique a des limites. Dans le cas de nos formations, techniquement, la liste des stagiaires n’a pas de limite supérieure. Cependant, cette limite est définie par un autre paramètre qui, en soi, est une variable.
Il est donc impossible de représenter cette contrainte de manière graphique et nous devrions exprimer certaines contraintes en langage naturel.
Cependant, il existe depuis la version 1.1 d’UML un langage formel, OCL (Object Constraint Language). Le langage naturel est évidemment le plus facile à mettre en œuvre, à formuler et à comprendre. Mais il est également source d’ambiguïtés qu’OCL essaye d’éviter.
Cette formation n’est pas une formation UML/OCL, ce sujet ne sera pas abordé ici.