Le blog que vous avez cité exagère un peu sa revendication. FP n'élimine le besoin de modèles de conception. Le terme «modèles de conception» n'est tout simplement pas largement utilisé pour décrire la même chose dans les langages FP. Mais ils existent. Les langages fonctionnels ont de nombreuses règles de bonnes pratiques de la forme "lorsque vous rencontrez le problème X, utilisez du code qui ressemble à Y", ce qui est fondamentalement ce qu'est un modèle de conception.
Cependant, il est vrai que la plupart des modèles de conception spécifiques à la POO sont à peu près non pertinents dans les langages fonctionnels.
Je ne pense pas qu'il devrait être particulièrement controversé de dire que les modèles de conception en général n'existent que pour combler les lacunes du langage. Et si une autre langue peut résoudre trivialement le même problème, cette autre langue n'aura pas besoin d'un modèle de conception pour cela. Les utilisateurs de cette langue ne savent peut-être même pas que le problème existe , car ce n'est pas un problème dans cette langue.
Voici ce que le Gang of Four a à dire à ce sujet:
Le choix du langage de programmation est important car il influence son point de vue. Nos modèles supposent des fonctionnalités de langage de niveau Smalltalk / C ++, et ce choix détermine ce qui peut et ne peut pas être implémenté facilement. Si nous supposions des langages procéduraux, nous aurions pu inclure des modèles de conception appelés "héritage", "encapsulation" et "polymorphisme". De même, certains de nos modèles sont pris en charge directement par les langages orientés objet moins courants. CLOS a, par exemple, plusieurs méthodes qui réduisent le besoin d'un modèle tel que Visitor. En fait, il y a suffisamment de différences entre Smalltalk et C ++ pour signifier que certains modèles peuvent être exprimés plus facilement dans une langue que dans l'autre. (Voir Iterator par exemple.)
(Ce qui précède est une citation du livre Introduction to the Design Patterns, page 4, paragraphe 3)
Les principales caractéristiques de la programmation fonctionnelle comprennent des fonctions comme valeurs de première classe, curry, valeurs immuables, etc. Il ne me semble pas évident que les modèles de conception OO se rapprochent de ces caractéristiques.
Quel est le modèle de commande, sinon une approximation des fonctions de première classe? :) Dans un langage FP, vous passeriez simplement une fonction comme argument à une autre fonction. Dans un langage OOP, vous devez encapsuler la fonction dans une classe, que vous pouvez instancier puis transmettre cet objet à l'autre fonction. L'effet est le même, mais dans la POO, cela s'appelle un modèle de conception, et cela prend beaucoup plus de code. Et quel est le modèle d'usine abstrait, sinon curry? Passez les paramètres à une fonction un peu à la fois, pour configurer le type de valeur qu'elle crache lorsque vous l'appelez finalement.
Alors oui, plusieurs modèles de conception GoF sont rendus redondants dans les langages FP, car il existe des alternatives plus puissantes et plus faciles à utiliser.
Mais bien sûr, il existe encore des modèles de conception qui ne sont pas résolus par les langages FP. Quel est l'équivalent FP d'un singleton? (Ignorant un instant que les singletons sont généralement un modèle terrible à utiliser.)
Et cela fonctionne aussi dans les deux sens. Comme je l'ai dit, FP a aussi ses modèles de conception; les gens ne les considèrent généralement pas comme tels.
Mais vous avez peut-être traversé des monades. Quels sont-ils, sinon un modèle de conception pour "faire face à l'état global"? C'est un problème si simple dans les langages POO qu'aucun modèle de conception équivalent n'existe là-bas.
Nous n'avons pas besoin d'un modèle de conception pour "incrémenter une variable statique" ou "lire à partir de ce socket", car c'est exactement ce que vous faites .
Dire qu'une monade est un modèle de conception est aussi absurde que de dire les entiers avec leurs opérations habituelles et l'élément zéro est un modèle de conception. Non, une monade est un modèle mathématique , pas un modèle de conception.
Dans les langages fonctionnels (purs), les effets secondaires et l'état mutable sont impossibles, à moins que vous ne les contourniez avec le «modèle de conception» monade, ou l'une des autres méthodes permettant la même chose.
De plus, dans les langages fonctionnels qui prennent en charge la POO (tels que F # et OCaml), il me semble évident que les programmeurs utilisant ces langages utiliseraient les mêmes modèles de conception disponibles pour tous les autres langages POO. En fait, en ce moment, j'utilise F # et OCaml tous les jours, et il n'y a pas de différences frappantes entre les modèles que j'utilise dans ces langages et les modèles que j'utilise lorsque j'écris en Java.
Peut-être parce que vous pensez encore impérativement? Beaucoup de gens, après avoir traité des langues impératives toute leur vie, ont du mal à abandonner cette habitude lorsqu'ils essaient un langage fonctionnel. (J'ai vu quelques tentatives assez drôles de F #, où littéralement chaque fonction n'était qu'une chaîne d'instructions «let», essentiellement comme si vous aviez pris un programme C et remplacé tous les points-virgules par «let». :))
Mais une autre possibilité pourrait être que vous n'avez tout simplement pas réalisé que vous résolvez des problèmes de manière triviale, ce qui nécessiterait des modèles de conception dans un langage OOP.
Lorsque vous utilisez le curry ou passez une fonction comme argument à un autre, arrêtez-vous et réfléchissez à la façon dont vous feriez cela dans un langage POO.
Existe-t-il une vérité dans l'affirmation selon laquelle la programmation fonctionnelle élimine le besoin de modèles de conception POO?
Oui. :) Lorsque vous travaillez dans un langage FP, vous n'avez plus besoin des modèles de conception spécifiques à la POO. Mais vous avez toujours besoin de modèles de conception généraux, comme MVC ou d'autres éléments non spécifiques à la POO, et vous avez plutôt besoin de quelques nouveaux "modèles de conception" spécifiques à FP. Toutes les langues ont leurs défauts, et les modèles de conception sont généralement la façon dont nous travaillons autour d'eux.
Quoi qu'il en soit, vous trouverez peut-être intéressant de vous essayer à des langages de FP "plus propres", comme ML (mon préféré, au moins à des fins d'apprentissage), ou Haskell , où vous n'avez pas la béquille OOP pour vous rabattre lorsque vous suis confronté à quelque chose de nouveau.
Comme prévu, quelques personnes se sont opposées à ma définition des modèles de conception comme "corriger les lacunes dans un langage", voici donc ma justification:
Comme déjà dit, la plupart des modèles de conception sont spécifiques à un paradigme de programmation, ou parfois même à un langage spécifique. Souvent, ils résolvent des problèmes qui n'existent que dans ce paradigme (voir monades pour FP, ou usines abstraites pour OOP).
Pourquoi le modèle d'usine abstrait n'existe-t-il pas dans FP? Parce que le problème qu'il essaie de résoudre n'existe pas là-bas.
Donc, si un problème existe dans les langues OOP, qui n'existe pas dans les langues FP, alors clairement c'est une lacune des langues OOP. Le problème peut être résolu, mais votre langue ne le fait pas, mais nécessite un tas de code standard pour contourner ce problème. Idéalement, nous aimerions que notre langage de programmation élimine comme par magie tous les problèmes. Tout problème qui persiste est en principe une lacune de la langue. ;)