Les Design pattern en Ruby ou Python

Si on regarde les Design Patterns, on remarque que beaucoup utilise des interfaces (ou des classes abstraites).

Mais en Python ou Ruby, elles n’existent pas à cause/grâce au typage dynamique, du coup que deviennent les patterns qui les utilisent ? Ils sont re-désignés pour fonctionner sous ses langages ?

J’ai trouvé un lien intéressant sur ce sujet:
The (lack of) design patterns in Python

Salut,

Tout d’abord, c’est un sujet intéressant et je remercie l’auteur d’avoir lancé cette discussion sur le forum.

Concernant Python, l’absence d’interfaces n’est pas liée au typage dynamique mais au principe de duck typing, PHP est aussi un langage à typage dynamique mais dispose bien d’interfaces.

De même, Python dispose bien depuis sa version 2.6 de classes abstraites.

L’explication est la même concernant Ruby.

Merci

Bonjour, 100% d’accord avec @icefield. Je vais même plus loin.
En gros oui ça change et tant mieux. D’ailleurs ça changera ton approche aussi.
Je ne dis pas “design patterns considered harmful” mais “quand le pattern parle des recettes pour résoudre tel problème avec telle idée, il faut s’accrocher au problème et à l’idée, pas au pattern”.


Que sont les design patterns ? Pour beaucoup des auteurs et architectes (Grady Booch, Kent Beck, Martin Fowler, Mel Conway) les choses qui les ont rendus célèbres (UML, Agile, archi, organisation) ne sont pas “le guide ultime” mais “une catégorisation à un instant T de réponses, à évoluer”.

J’ai du mal à retrouver LE podcast que je voulais mais l’auteur disait “les Design Patterns n’ont pas de valeur en soi, il ne faut pas apprendre le bouquin, par contre le livre est une galerie de solutions communes qui te permettent de reconnaitre ce que tu as fait ou ce que tu récupères d’un collègue, afin d’en discuter avec lui, et avec un commentaire sur les avantages et inconvénients”.

Je crois que c’est le CodeNewbie avec Dave Thomas mais il n’ a pas de transcription texte :
http://www.codenewbie.org/podcast/the-pragmatic-programmer-i

Mais bon, on va se mettre sur le transcript de ce podcast : http://completedeveloperpodcast.com/episode-34/ et dire “un pattern est une réponse commune à un problème commun, avec des outils communs” et donc quand les outils changent (de C++ à Ruby) la réponse va changer aussi (l’idée non, l’implémentation et les astuces oui).


Mon avis personnel c’est que le système de typage dans les “OOP en mode héritage (C++ Java, à la Bjarne Stroustrup)” est très contraignant (d’où ton focus sur les classes) et donc tu DOIS tricher. La plupart de ces patterns sont pour moi des contournements tordus alors que le problème est simple.
La solution de Ruby et son système (peut-être trop) permissif fait qu’un visiteur c’est juste .map et… c’est tout. C’est une “OOP en mode messages (Objective C; Smalltalk, Erlang, à la Alan Kay)” et c’est selon moi la seule vraie manière de faire de la prog orientéé objet.

Bon courage et bonne OOP !
Pour Ruby n’hésitez pas à lire POODR de Sandi Metz, il y a de l’héritage smalltalk et donc des conseils de conception qui valent de l’or :)

1 « J'aime »

@blueicefield et @abelar_s, je suis d’accord avec vous mais trouve que vous éludez un peu facilement la question.

je me focalise sur Python et Ruby car ils sont en passe de devenir les langages leaders (c’est déjà le cas pour Python) et leurs concepts de base apportent beaucoup de changements de fond.

Si je cite le podcast:

Design patterns create a common language platform for developers no matter their preferred language to communicate and develop best practices.
BJ and Will as .NET developers are able to discuss the same concepts with Ruby or Python developer friends.

These are fundamental elements of how you design software

C’est ce que j’ai toujours entendu, les design pattern c’est:

  1. un fondamental
  2. cross langage

Sauf que les concepts de Ruby et Python rendent les 3/4 pattern inutiles.

Du coup, qu’est-ce qu’on en fait (des pattern) ?? Si un jeune développeur vous demande s’il doit apprendre les pattern, vous lui répondez quoi ???
Car, perso, j’aurais tendance à lui dire faire l’impasse, il fera plus de merde à essayer de les appliquer que de coder sans (en Ruby ou Python).

1 « J'aime »

Beaucoup de design pattern sont déjà implémentés dans les framework et sont bien conçus. Donc “à quoi bon les apprendre” ?
Ben déjà yen a plein qui sont pas intégrés par défaut.
De plus la pensée évolue donc de nouveaux patterns apparaissent fréquemment.
Ça alimente de nouveaux défis et d’autres façons de voir les choses.
En outre il n’y a pas que les patterns de code. Il y en a énormément : Il y en a pour l’architecture software, urbanisation SI, puis les patterns s’appliquant à chaque domaine métier, etc…

Du point de vue du junior, il peut deja comprendre pourquoi ils existent / apports/ limites, les reconnaître dans du code existant, ce qui fait un bad pattern, imaginer des nouveaux, s’inspirer des problématiques actuelles qui se transforment à leur tour en patterns.

Hello,

Je vais tenter de faire une réponse globale en espérant répondre à à peu près tout.

Un design pattern, c’est la réponse communément acceptée à un problème donné dans un cadre donné de modélisation objet. Les patterns apportent des éléments de langage que tu peux utiliser pour décrire les internes et en une certaine mesure les externes d’un soft.

Si tu modélises les concepts de ton programme à partir d’objets, que la nature de ces objets soit vérifiée à la compilation (typage statique) ou à l’exécution (typage dynamique), la modélisation reste la même. Un typage dynamique n’est en rien incompatible avec la modélisation objet, pour exemple le langage ultime de la modélisation objet: smalltalk qui est un langage à typage dynamique. Il est même courant d’utiliser des design pattern dans des langages qui n’implémentent pas l’approche objet (ex: C).

Beaucoup de langages orientés objet n’implémentent pas forcément une approche objet pure et proposent souvent d’autres concepts (ex: l’approche fonctionnelle, d’autres concepts comme les traits, …). La question devrait à mon avis ne pas être «est-ce que je dois apprendre les design pattern ?» mais «comment est-ce que je dois les apprendre ?»

La réponse à cette question est à mon avis la suivante :
Programme, lis des programme, participe à la construction de gros logiciels. Identifie les problématiques de modélisation qui apparaissent et demande toi quelle est la façon la plus élégante d’y répondre. Dans beaucoup de cas, tu auras un design pattern qui pourra s’appliquer, d’où la bible du GoF.
Maintenant que tu as identifié le problème, une solution possible, demande toi si cette solution est la plus pragmatique. Si c’est le cas, implémente la. Sinon prend l’autre solution plus pratique.

Je pense que de bonnes références pour approfondir ce type de sujet c’est les livres sur le refactoring.

Souviens toi que l’important lorsque l’on programme, c’est pas le nombre de lignes que l’on peut économiser, mais la maintenabilité du code écrit. Un logiciel peut vivre des années pendant lesquelles de nouveaux concepts peuvent émerger. Tu dois te préparer à pouvoir remanier l’existant pour t’y adapter, même si tu ne les connais pas encore. À ce niveau là, les patterns sont un outil pour t’y aider. Pour exemple, je bosse sur un outil énorme qui a plus de 10 ans où se mêlent java, C, js (serveur), bash (awk, …), ruby, python, et probablement d’autres que j’oublie. Monter en compétence sur le projet demande plusieurs mois, voire années et lorsque l’on tombe sur un pattern que l’on reconnaît, c’est quand même agréable de sortir un peu de ce brouillard de spaghetti…

Maintenant, le fait que tu n’ais pas d’interfaces ou que le typage soit moins contraignant, ce n’est que des contraintes en plus ou en moins dans l’implémentation des patterns.

Voilà grosso modo, j’espère avoir pu éclairer ta lanterne. Bon courage

1 « J'aime »

Et les Monads ? Figurent elles dans le joyeux zoo des design patterns ?
Si non, se pourrait-il que la vision du monde qu’offrent les DPs soit trop restrictive ?

@sgendrot ben voilà je suis d’accord avec ton point de vue :)
D’une part tu avais la réponse en toi et d’autre part je n’ai rien dit d’autre.

Par contre je tiens à ma distinction OOP héritage et OOP messages. C’est quelque chose dont peu de gens parlent : OOP est “forcément bien” et “forcément opposée à FP” (prog objet vs prog fonctionnelle) alors qu’en réalité OOP et FP ont tout pour s’entendre, et les deux saveurs d’OOP que je distingue ont tout qui les sépare :)

Donc oui @Delapouite, les monades sont complètement des éléments de réponse que chaque dev devrait avoir dans sa boite à outils, tout comme sa bibliothèque standard et ses frameworks, pour répondre au mieux à tous les probèmes !

Maaaiiiiis voilà, monade est un mot compliqué alors on fait semblant d’avoir peur. Ou pire pour cacher sa peur, on prétend que la FP “n’est pas pour moi” ou pire “pas pour mon problème” (c’est possible j’imagine) sauf qu’en général les gens disent ça avant d’avoir étudié le problème et la FP (et ça c’est de la malhonnêteté intellectuelle). ;)

Je vois pas en quoi les messages en objet et l’héritage s’opposent : ce sont deux composantes d’une même théorie qui sont implémentés de différentes façons suivant les langages. La composition sert à décrire les aggrégations d’objets, l’héritage permet de spécialiser la nature des objets et les messages à décrire les interactions entre les objets.

Les lambda/monades/… (on dira fonctions) sont des éléments de langage au même titre que les procédures, boucles, conditionnelles, … Les fonctions offrent juste une façon d’écrire des algorithmes, il ne s’agit pas d’élément architecturaux.
Les langages fonctionnels apportent leur lot de notions pour une autre façon d’écrire des algorithmes : mapping, folding, reduce, ordre suppérieur, …

Autant, opposer approche fonctionnelle et approche procédurale pour l’écriture d’algorithmes fait du sens, en particulier en ce qui concerne la gestion des données, mais opposer fonctionnel et objet n’a que peu de sens : ça ne s’intéresse pas au même niveau d’abstaction (même s’il existe certains “overlaps” comme pattern strategy vs. switch/case).

Par contre lorsque l’on prend du recul par rapport à l’architecture d’un programme et que l’on s’intéresse à des algorithmes distribués, on retrouve des choses qui ressemblent à la programmation fonctionnelle mais pour moi, ça n’en est pas vraiment (je pense aux map/reduce et consort)

En d’autres termes, on a plusieurs niveaux d’abstraction :

  • traitement des données, traitement de la logique interne du programme : procédural, structuré, fonctionnel
  • gestion de l’architecture bas niveau d’un logiciel : approche orientée objet (même en C je me rapproche d’une modélisation à base d’objets)
  • gestion de l’architecture haut niveau : approche composant, approche service, algos distribués, …
1 « J'aime »

Bah justement j’ai pas vraiment l’impression. Quand on recherche sur le net, on tombe surtout sur les design patterns habituels.
La plupart datent des années 94/95 et ne sont plus adaptés au langages dynamiques:

Mais même là, les critiques datent de 15 ou 20 ans.

Enfin, en 15/20 ans, ya bien quelqu’un qui a dû faire une “compilation” des nouveaux Design Pattern pour du Ruby/Python.

1 « J'aime »
Human Coders - Le centre de formation recommandé par les développeur·se·s pour les développeur·se·s