Les designs patterns une preuve de faiblesse du langage

10/10/2013

Le titre peut faire frémir et vous pensez que je vais lancer un troll bien dégoulinant sur cette page - non ce n’est pas le but. Vous allez voir que je n’ai rien contre les designs patterns mais qu’une réflexion sur leur existence peut vous amener à y réfléchir quand vous choisirez un langage pour implémenter vos projets. Si ce post vous offusque, ne le lisez pas…

Hier, je discute avec mes collègues ingénieurs en développement à propos des patterns existants nativement dans certains langages, et je ne sais pas pourquoi, je lance la phrase “Rob Pike disait dans une conférence que les design patterns sont la démonstration de la faiblesse d’un langage”. Je ne me souvenais plus exactement quelle conférence, mais je l’ai retrouvé, c’est “Public Static Void” à voir ici http://www.youtube.com/watch?v=5kj5ApnhPAE et là http://fr.slideshare.net/120bi/public-staticvoidrobpikeosconjuly2210 . En réalité, je me rend compte que cette phrase est d’un autre personnage cité dans la conférence, c’est Norvig qui raconté ceci.

Patterns are demonstration of weakness in a language P.Norvig

Il le démontre en réalité en parlant du pattern Iterator dans son article http://home.pipeline.com/~hbaker1/Iterator.html

Personnellement je me suis fais cette réflexion il y a bien longtemps. Lorsque je faisais parti de l’équipe de développement de Copix (http://www.copix.org) Gérald Croës donnait des conférences sur le sujet. Et je me disais en l’écoutant “ouais en gros les designs patterns ça sert à régler des problèmes récurrents quand on a pas la solution nativement”… J’étais pas loin de ce que raconte R.Pike et P.Norvig.

Prenons un exemple de pattern, le Thread Pool. L’idée est de définir une pile limitée en taille qui va accepter des threads à lancer. Quand un thread est terminé, il laisse la place à un autre, pendant que les autres threads déjà dans la pile continuent de tourner.

Vous vous dites que c’est simple, c’est vrai. Aujourd’hui Python, Java, Ruby, et autres langages haut niveau permettent de faire un “Pool” et des “Threads”. Mais le Thread Pool doit être implémenté, et ce pour une raison simple: ils n’existent pas nativement dans le langage.

Certains langages par contre ont des types permettant de gérer des tâches concurrentes (ou parallèles, cela dépend du langage et de l’implémentation) nativement sans avoir besoin d’une classe ou d’un type spécifique, et de même pour les “pool” qui sont gérés eux aussi par des types prévus à cet effet. Je pense à Go, Erlang…

Je ne suis pas en train de dire que Go et/ou Erlang sont plus puissant que Java ou Python, mais que leur force réside dans le fait que vous pouvez vous abstraire de beaucoup de patterns parce que le langage est prévu pour cela.

Je vais un peu plus loin dans mon idée. Les design patterns existent depuis des lustres, en fait on en entend parler depuis les années 80 en tant que tel mais des “patterns” existent depuis les années 50 à l’époque où l’on développait en assembleur. Le simple fait de pousser des valeurs dans un espace mémoire pour laisser la pile propre au “sous-routines” était une idée ingénieuse qui règle un souci récurrent dans les langages “Assembleur”.

Quand est né le C, ce problème de mémoire à gérer a disparut pour ce cas. Le langage a supprimé l’utilisation d’un pattern en le rendant transparent. On peut en déduire que la méthode de déplacement des registres en mémoire pour l’utilisation de sous-routines (en tant que pattern) était une faiblesse des langages Assembleur. Et là, je ne crache pas sur le langage, je ne fais que noter une complexité réduite par un langage dont le niveau d’abstraction est plus haut.

Aujourd’hui, dans la plupart des langages que j’utilise (PHP, Python, C/C++, Java, …) je vois des implémentations de design patterns quasi identiques: Iterator, Singleton, Factory… tous sont des implémentations non natives alors que le développeur en a besoin tous les jours.

Deux options se présentent:

  • avoir les implémentations existantes
  • utiliser un langage qui s’en abstrait

La première solution est celle que l’on empreinte finalement presque tout le temps, car changer de langage dans une infrastructure logiciel complexe est de l’ordre de l’impossible.

La seconde solution fonctionne dans le cas d’un nouveau projet et si vous êtes certain que l’impact ne sera pas conséquent dans une infrastructure. Cela dit, ces langages sont généralement relativement nouveaux et sont laissés de coté en faveur d’un langage plus répandu, et qui n’offre pas ces évolutions.

Donc, en en revient à mon plaidoyer, si tous les langages demandent une implémentation non native d’un pattern que le langage ne résous pas, alors que de nouveaux langages s’en abstraient, on en revient au pattern “sous-routine” réglé par le langage C face à l’assembleur. Vous ne pouvez pas ne pas admettre le fait: le langage que vous utilisez a une faiblesse, même si la solution existe le problème est bien là.

Lisez la page: http://en.wikipedia.org/wiki/Software_design_pattern, juste les premières lignes…

En informatique, et plus particulièrement en développement logiciel, un patron de conception (en anglais : « design pattern ») est un arrangement caractéristique de modules, reconnu comme bonne pratique en réponse à un problème de conception d’un logiciel. Il décrit une solution standard, utilisable dans la conception de différents logiciels.

Il n’y a pas d’équivoque, le design pattern est une réponse à un problème standard, mais il manque l’information , je complète la dernière phrase “Il décrit une solution standard, utilisable dans la conception de différents logiciels si le langage ne propose pas de solution native

Et de plus, prenons une phrase dans le préambule de la page wikipedia: “Ils ont une influence sur l’architecture logicielle d’un système informatique.” C’est étonnamment vrai et invraisemblable, car un pattern “standard” c’est à dire une solution à un problème, va vous forcer d’une part à l’implémenter mais aussi va influer sur la manière dont vous développez votre logiciel.

Ainsi, je ne peux pas définir un “pattern” autrement que par “une faiblesse” car si le langage ne vous impose pas d’implémenter une batterie d’implémentations qui influent sur votre code, alors il vous affranchi d’un problème et rend votre développement plus libre tout en respectant le standard du langage lui-même; et non pas d’une “bonne pratique” en “add-on” de langage… D’ailleurs, je me rend compte qu’encore une fois je suis sur la voie de R.Pike, car dans la même page où il cite “Norvig”, je vois qu’il parle de “add-ons” en parlant des patterns.

Voilà, c’est à peu près le fond de ma pensé. Je continue à utiliser des patterns dans mes développements quand le langage ne me permet pas de gérer certains aspects de conceptions, et je ne dis pas non plus que ces langages sont désuets, vieillots ou à oublier. Simplement, j’estime que les langages évoluent, que certains nouveaux apparaissent et qu’il ont la force de me permettre de me passer de patterns et par conséquent réduisent mes efforts.

Ça peut vous intéresser aussi


POO vs Composinting

Si vous vous êtes intéressé au langage “Go”, alors ...


Didacticiel Python Part 1

Je me suis développé un petit outil de load-balancing en ...


Mise à jour du blog en Go

Si vous connaissiez mon blog, vous avez remarqué qu’à ...


Golang, comment définir un destructeur

Si vous avez un peu bourlingué sur Go, vous savez ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.