• 12 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 07/03/2022

Décomposez un problème de programmation orientée objet

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Comment décomposer un problème de programmation

Lorsque nous sommes confrontés à un problème de programmation, que ce soit sous la forme d’un projet OpenClassrooms ou dans un environnement de travail Agile, nous devons traduire les concepts et notre compréhension du problème en code.

Pour ce faire, vous affinerez probablement un processus qui vous convient au cours de votre carrière dans le code, et vous le modifierez en fonction du projet et des différents processus et contraintes avec lesquels vous travaillerez.

Certains développeurs préfèrent planifier à l’avance, et identifier chaque élément du système avant de toucher leur IDE. Vous pouvez identifier les objets et opérations qui doivent trouver leur place dans le système, en dessinant des diagrammes (par exemple, des diagrammes UML comme vous pourrez voir dans le cours Appliquez le principe du Domain-Driven Design à votre application), et en prenant des notes.

D’autres développeurs préfèrent adopter une approche plus concrète par le prototypage, et essaieront de comprendre le problème par la construction. Avec cette approche, vous devez être prêt à jeter du code à mesure que votre design se développe. Vous pouvez commencer avec une partie du problème, essayer différentes approches, et utiliser du code et des classes provisoires pour modéliser les interactions entre différentes parties de votre système.

Prenez une minute pour peser les bénéfices et les points faibles de ces deux approches. Y aurait-il un moyen de les combiner ?

Quel que soit le process que vous décidez d’utiliser au final, il y a quelques éléments que vous devez découvrir.

Les fonctionnalités

Que doit faire votre programme ou fonctionnalité ? De quelles fonctionnalités additionnelles pourrait-on avoir besoin à l’avenir ? Comment vous assurer que votre code soit extensible, de façon à ce que ces modifications soient possibles ?

Les objets

Quels sont les objets qui existent dans l’espace du programme ? Quelles sont les responsabilités de chacun de ces objets ? À quoi servent-ils ? Quelles sont les relations entre ces objets ?

Nous avons parlé d’héritage pendant ce cours, lorsqu’une classe « is-a » (« est-une ») version plus spécialisée d’une autre classe. Il existe également des relations de composition, que nous avons évoquées sans les nommer, qui désignent des relations « has-a » (« a-un »). Par exemple, une voiture a un volant – le volant pourrait être stocké comme variable à l’intérieur de la voiture. C’est une façon d’imbriquer les objets entre eux, pour éviter d’avoir un seul gros objet qui ferait trop de choses différentes.

Les interfaces

Dans quelle mesure est-ce que ce code va interagir avec d’autres systèmes et d’autres parties de code ? À quoi ressembleront les interfaces – les méthodes, fonctions et autres fonctionnalités qui relient votre programme aux autres ?

Avec ces questions à l’esprit, mettons-nous à la pratique ! Dans le screencast ci-dessous, je vous montrerai un exemple avec l’héritage, l’interface et la composition – après, ce sera à vous de mettre en pratique ce que nous venons de voir ensemble :

Au fil de votre parcours OpenClassrooms, et au-delà encore de votre carrière de développeur, vous déroulerez ce processus de nombreuses fois – ce qui vous donnera beaucoup de temps pour l’affiner et intégrer de nouvelles idées et méthodes.

À vous de jouer : décomposez un problème de programmation

À vous de jouer

Votre bibliothèque de films de science-fiction s'agrandit de jour en jour, au point de ne plus y voir clair ! 🛸 Vous décidez de créer une application qui vous permettra de retrouver facilement vos films.

Il vous faut d’abord concevoir la structure du code. Pour cela, inspirez-vous des fonctionnalités listées ci-dessous :

  • Un film possède un nom, une date de création, et un « lieu » (dans ma bibliothèque ou chez un ami).

  • Il existe deux types de films : les films VHF et les films DVD.

  • Chaque film est listé dans ma bibliothèque virtuelle. Ils sont triés par date et par nom.

  • Je peux aussi trier la liste par type de film (VHF ou DVD).

  • Je peux récupérer un film au hasard.

  • J’ai des amis, qui possèdent un nom et éventuellement un film que je leur ai prêté.

  • Je peux avoir la liste des films prêtés.

  • Je peux savoir qui possède un de mes films.

Pour mener à bien cette tâche, je vous donne les données de base (des films et des amis) :

films = [
("Blade Runner (1982)", "vhf"),
("Alien : Le 8ème Passager (1979)", "vhf"),
("2001 : L'Odyssée de l'espace (1968)", "VhF"),
("Matrix (1999)", "DVD"),
("Interstellar (2014)", "dvD"),
("L'Empire contre-attaque (1980)", "vhf"),
("Retour vers le futur (1985)", "vhf"),
("La Guerre des Étoiles (1977)", "vhf"),
("L'Armée des 12 singes (1995)", "dVd"),
("Terminator 2 : Le Jugement dernier (1991)", "DVD"),
]
friends = [
("Paul", "Blade Runner"),
("Lucie",),
("Zoé", "Terminator 2 : Le Jugement dernier"),
]

Mais c’est quoi ces données ? Elles sont mal formatées, j’ai des différences de majuscule pour le type de film, et la date est dans le nom ! 🙅‍♂️

Bienvenue dans le monde du traitement des données ! Dans le web, lorsque vous récupérez les données d’ailleurs, vous aurez souvent ce genre de résultat. Ne faites donc jamais confiance aux données entrantes. 😅

Dans notre cas, nous allons devoir les nettoyer avant de les utiliser. C’est peut-être l’occasion d’écrire des classes de « nettoyage » ?

Vous utiliserez ce que nous avons appris jusque là (réfléchir aux relations entre classes, utiliser plusieurs modules et packages…), et vous lancerez enfin un code de résolution qui permettra de vérifier vos fonctionnalités.

Voyons ensemble comment lire ce code :

En résumé

  • Lorsque nous rencontrons un problème de programmation, nous devons décomposer le problème en parties plus petites.

  • Nous pouvons prendre en compte les fonctionnalités souhaitées, les objets du domaine, et le code autre avec lequel l’interface doit être assurée dans le design.

  • Apprendre à décomposer un problème est une compétence que l’on perfectionne grâce à la répétition et à l’expérience.

Nous avons couvert le design et la structure, ce qui ne nous laisse qu’une chose de plus à faire : gérer les erreurs. Dans le chapitre suivant – qui est aussi le dernier – nous allons gérer et créer des Exceptions.

Exemple de certificat de réussite
Exemple de certificat de réussite