Avantages de la programmation orientée objet
- En programmation orientée objet (POO), l'élément de base est la classe (un prototype) qui peut ensuite être instantiée en objet
-
Une classe définit des champs et méthodes récupérant des données sur ces champs et/ou les modifiant
- Les champs sont soit des types primitifs (i.e. des types de base fournis par le langage)...
- ...ou alors des types classe définis par l'utilisateur ou une bibliothèque
-
On construit des programmes complexes en assemblant différents objets entre-eux et en exploitant les concepts suivants :
-
La composition : un objet peut avoir pour valeurs de champ des références vers d'autres objets
- Cela permet d'obtenir un objet complexe qui couvre des problématiques complexes de modélisation
-
La délégation : un objet peut déléguer la modélisation de certaines données ou la réalisation d'actions à d'autres objets
- Cela permet de masquer certains détails d'implantation aux objets qui font appel à lui ; seules des méthodes publiques sont exposées
- On peut ainsi avoir des objets réalisant le même type de tâche mais à l'aide de structures de données différentes
-
La composition : un objet peut avoir pour valeurs de champ des références vers d'autres objets
-
Un bon usage de la POO permet de répondre à certaines problématiques essentielles de la conception de logiciels :
-
La modularité : il est conseillé de découper hiérarchiquement un projet logiciel en différentes composantes indépendantes (ou du moins de minimiser les inter-dépendances)
- Cela cloisonne les différentes fonctionnalités tout en permettant une future liaison entre-elles
- Cela facilite l'évolution indépendante des composantes (et le travail en équipe)
- Il est possible de greffer simplement de nouvelles composantes
- Si les composantes sont bien identifiées, cela limite la duplication de code, le volume de code... et par conséquence le coût de maintenance
-
L'extensibilité
- De nouvelles fonctionnalités doivent facilement être implantables (en modifiant le minimum de code existant)
-
C'est un des objectifs du système de sous-typage et d'héritage de classes :
- On peut créer des classes dérivées avec des informations additionnelles et des nouveaux comportements
- Ou au contraire on peut introduire des classes plus abstraites afin de factoriser certaines caractéristiques
-
L'optimisation des performances (en mémoire et en temps)
- Il faut parcimonieusement créer de nouveaux objets
- Il faut rendre inaccessible les objets lorsque l'on en a plus besoin (attention aux fuites de mémoire !)
-
La modularité : il est conseillé de découper hiérarchiquement un projet logiciel en différentes composantes indépendantes (ou du moins de minimiser les inter-dépendances)
Objectif des design-patterns (ou patrons de conception pour les francophones) :
- Formaliser, partager et promouvoir des bonnes pratiques pour l'architecture de code en utilisant les capacités de la POO
Pourquoi étudier les design patterns ?
-
Cela permet de redécouvrir sous une forme formalisée des concepts que l'on utilisait déjà
- Comme M. Jourdain, nous utilisons déjà des design patterns sans le savoir !
- Cela permet d'apprendre aussi de nouveaux paradigmes pour architecturer son code
- L'objectif n'est plus d'écrire uniquement du code qui fonctionne mais du code architecturé élégamment
Promoteurs des design-patterns
- Utilisés de façon plus ou moins informelle depuis les débuts de la POO
-
Le gang of four (Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides) a entrepris de réaliser une taxonomie des principaux patterns utilisés
- Livre de référence avec les principaux patterns : Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley), 1994
Champ d'application des design-patterns
- Tout langage permettant le programmation orientée objet est concerné par l'utilisation des design-patterns
-
Certains patterns sont plus ou moins simples à implanter selon les spécificités du langage
- Soit on cherche à s'adapter aux possibilités des langages...
- ... mais dans certains cas, des langages se sont adaptés pour faciliter l'implantation de certains patterns
- On cherche à éviter certains types de pratiques architecturales (on parle d'anti-pattern) qui peuvent réduire les qualités de modularité, d'extensibilité et de facilité de maintenance d'un programme.
Design-patterns et héritage
- La plupart des design-patterns ne requièrent pas l'usage de l'héritage de classe
- Les design-patterns requièrent plutôt que l'on utilise des interfaces (qui sont ensuite implantées)
-
Notons aussi que les langages de programmation modernes ne permettent pas nécessairement l'héritage de classes :
- Cas de Rust : les traits correspondent aux interfaces en Java mais il n'existe pas de classes ni d'héritage
- Cas de Go : on peut définir des interfaces mais aucun héritage n'est disponible pour les structures : une structure satisfait une interface par duck-typing
Une visite guidée des design-patterns les plus courants
- Tout d'abord nous passons en revue quelques anti-patterns à éviter absolument dans du code.
- Ensuite nous examinons les principes SOLID popularisés par Robert Martin
On classe les design-patterns en différentes catégories :
- Les patterns créationnels proposant des façon de créer de nouveaux objets.
- Les patterns structurels s'intéressant à la façon dont on organise les classes.
- Les patterns comportementaux afin d'implanter des interactions entre objets.
- Les patterns de concurrence afin de faire coexister plusieurs fils d'exécution et d'organiser l'accès et l'écriture de données partagées.