Introdution à la POO

Introduction à la POO #

Paradigme objet #

La POO est un paradigme de programmation (style de programmation) basé sur le concept d’objet. Celui-ci permet de représenter un concept concret (p. ex: une imprimante, une machine à café connectée, un serveur http…) ou abstrait (p. ex: un rendez-vous, une consultation…) en y rassemblant les données et les traitements qui s’y appliquent. La formalisation date des années 1960/1970. Les langages orientés objet les plus connus sont: Simula 67, Smalltalk (1970), C++ (1983), Eiffel (1986), Python (1991), Ruby (1995), Java (1996), JavaScript (1996) et C# (2002).

Objectifs #

Un premier objectif est de contenir un état dans l’objet tout en cachant sa structure et son implémentation. L’objet doit offrir un ensemble de fonctionnalités utiles permettant sa manipulation. Il devient dès lors impossible d’accéder ou de modifier la structure interne d’un objet. Le changement d’état se fait uniquement par les fonctionnalités offertes, appelées méthodes, qui doivent permettre de passer d’un état cohérent de l’objet à un autre état cohérent. Les langages typés permettent également de donner des noms explicites à des structures de données, généralement agrégées à l’aide de plusieurs autres types (par exemple: Printer, Computer…).

Un deuxième objectif est de permettre un code extensible et une bonne abstraction. Une extension permet de rajouter un nouveau type sans modifier le code existant de la logique métier. Imaginons que nous souhaitons manipuler des périphériques réseau : des imprimantes et des ordinateurs. Chaque périphérique réseau possède un comportement commun : il est possible de l’éteindre, de le démarrer, de le redémarrer et de connaître son statut. Chaque modèle de chaque périphérique contient sa propre logique pour ces fonctionnalités. Le périphérique est une bonne abstraction car il n’est pas nécessaire de savoir s’il s’agit d’une imprimante ou d’un ordinateur. Si nous souhaitons redémarrer tous les périphériques réseau, nous voulons juste appeler la fonctionnalité (méthode) reboot:

1
2
3
for (Device d: allComponents) { 
  d.reboot();
}

Cette fonctionnalité est appelée méthode. Il s’agit d’une fonction rattachée à un objet particulier. Supposons maintenant que nous souhaitons ajouter un nouveau périphérique, disons une machine à café connectée. Le code existant ne doit pas être modifié. Seul le nouveau type devra décrire comment il redémarre:

1
2
3
4
5
class CoffeeMachine implements Device {
  void reboot() {
    /* logic to reboot an IOT coffee machine */
  }
}

Enfin, un dernier objectif est de permettre un code plus expressif, par ex:

myDocument.sendTo(myPrinter).withQuantity(10).withFormat("A4").print();

Vous l’aurez sans doute remarqué : la POO se focalise uniquement sur le comportement et non sur la structure et la mise en oeuvre. Seul le comportement est exposé, le reste n’est que détail futile !

“Codez pour des humains, pas pour des machines”. Cette façon de penser aide à écrire un code propre. Un code écrit une fois est lu une quantité de fois (revue de code, debug, refactoring…). Mettez tout en oeuvre pour vous concentrer sur l’expérience de l’utilisateur de votre librairie. Vous offrez un service à d’autres développeurs. Vous êtes auteur de votre code, ne l’oubliez pas. Vous avez donc des lecteurs. Pensez à eux !

Clean code always looks like it was written by someone who cares” (Michael Feathers)

Concept de classe #

Un objet est une instance d’une classe. Cette dernière permet de décrire le comportement et la structure de tous les objets appartenant à cette classe. Par exemple, le livre “Le Comte de Monte-Cristo” est un objet appartenant à la classe Book.

Deux familles de langages orientés objet

Il existe deux familles de langages orientés objet

  • Ceux basés sur les classes comme Java, C#, Scala, Python… En bref, une majorité.
  • Ceux basés sur les prototypes. JavaScript est l’exemple le plus connu:
    • ces langages n’ont pas de classes (même si depuis ECMAScript 2015, le mot-clé class offre un “sucre syntaxique” permettant de générer des fonctions “spéciales”. Réf: MDN)
    • un prototypes est un objet à partir duquel on crée de nouveaux objets

Caractéristiques #

Les caractéristiques de la POO sont:

  • L’encapsulation qui permet de cacher la structure et les détails d’implémentation.
  • L’héritage qui permet de créer des sous-types (une imprimante est un composant réseau).
  • Le polymorphisme (substitution d’un type par un sous-type: chaque fonction qui prend en argument un composant réseau peut recevoir une imprimante en argument).

Nous allons aborder l’héritage et le polymorphisme plus tard, mais vous pouvez déjà retenir le dernier terme. Nous verrons que le polymorphisme est l’intérêt principal de la POO. Il existe un polymorphisme de sous-typage, un polymorphisme ad-hoc (surcharge) et un polymorphisme paramétrique (les génériques).

Bon design POO #

Il est très difficile de réaliser une bonne conception orientée objet sans tomber dans les pièges d’un code spaghetti ou d’une code lasagne . L’objectif de ce cours n’est pas seulement de faire des programmes qui fonctionnent avec des objets, mais de le faire correctement avec les standards de qualité modernes. Un code illisible a autant de qualités qu’un code faux.

Un code simple, lisible et concis ne veut pas dire qu’il est simpliste et qu’il a été fait rapidement. Il est par contre facile à comprendre et facile à maintenir. La simplicité devrait être un objectif de qualité.

Evitez la complexité, même pour justifier une performance. Réalisez un code simple et juste plutôt qu’un code performant, difficile à comprendre et probablement faux. Ne visez pas les performances avant d’avoir mesuré l’exécution et identifié où les mettre en oeuvre.

Quelques citations faisant l’apologie de la simplicité #

Le métier d’ingénieur ne consiste pas à trouver des solutions compliquées à des problèmes simples, mais à trouver des solutions simples à des problèmes compliqués. (devise de l’auteur)

La perfection est atteinte, non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retirer. (Antoine de Saint-Exupéry, Terre des hommes, 1939)

Les hypothèses suffisantes les plus simples doivent être préférées (principe utilisé en Science)

La simplicité est la sophistication suprême (principe du rasoir d’Ockham)

Premature optimization is the root of all evil (Donald Knuth, mathématicien, informaticien)

Ce que l’on conçoit bien s’énonce clairement, et les mots pour le dire arrivent aisément (Nicolas Boileau, l’Art poétique, 1674)

Any fool can make something complicated. It takes a genius to make it simple. (Woody Guthrie, Chanteur, 1912/1967)

Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it. (Alan Perlis, 1er Prix Turing en 1966/fondateur d’Algol)

Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function. (John Carmack, ingénieur en informatique, concepteur de nombreux jeux vidéo, actuellement directeur technique chez Oculus VR)












comments powered by Disqus