Depuis que j'ai entendu parler des Gang of Four (GoF) design patterns , il y a au moins 10 ans, j'ai l'impression que ces 23 modèles ne devraient être qu'un petit échantillon de quelque chose de beaucoup plus grand que je aime appeler le Pattern Space . Cet espace de modèle hypothétique comprend toutes les solutions recommandées (connues ou inconnues) pour les problèmes courants de conception de logiciels orientés objet.
Je m'attendais donc à ce que le nombre de modèles de conception connus et documentés augmente considérablement.
Cela ne s'est pas produit. Plus de 20 ans après la sortie du livre du GoF, seuls 12 modèles supplémentaires sont répertoriés dans l'article Wikipedia, dont la plupart sont beaucoup moins populaires que les originaux. (Je n'ai pas inclus les modèles de concurrence ici car ils couvrent un sujet spécifique.)
Quelles sont les raisons?
L'ensemble de modèles du GoF est-il réellement plus complet que je ne le pense?
L'intérêt de trouver de nouveaux modèles a-t-il chuté, peut-être parce qu'ils se sont avérés ne pas être très utiles dans la conception de logiciels?
Autre chose?
Lorsque le livre est sorti, beaucoup de gens pensaient de cette façon, et il y avait beaucoup d'efforts pour créer des "bibliothèques de modèles" ou même des "communautés de modèles". Vous pouvez toujours en trouver certains:
Mais alors...
L'intérêt de trouver de nouveaux modèles a-t-il chuté, peut-être parce qu'ils ne sont pas vraiment utiles dans la conception de logiciels?
Ça, beaucoup. Le point des modèles de conception est d'améliorer la communication entre les développeurs, mais si vous essayez d'ajouter plus de modèles, vous arrivez rapidement au point où les gens ne s'en souviennent pas. , ou les mémoriser, ou être en désaccord sur ce à quoi ils devraient ressembler exactement, et la communication n'est pas, en fait, améliorée. Cela se produit déjà souvent avec les modèles GoF.
Personnellement, j'irais encore plus loin: la conception de logiciels, en particulier une bonne conception de logiciels, est beaucoup trop variée pour être capturée de manière significative dans des modèles, en particulier dans le petit nombre de modèles dont les gens peuvent se souvenir - et ils sont beaucoup trop abstraits pour que les gens puissent rappelez-vous vraiment plus qu'une poignée. Donc, ils n'aident pas beaucoup.
Et beaucoup trop de gens deviennent amoureux du concept et essaient d'appliquer des modèles partout - généralement, dans le code résultant, vous ne pouvez pas trouver la conception réelle entre tous les singletons et les usines abstraites (complètement dénués de sens).
J'ai l'impression que ces 23 motifs ne devraient être qu'un petit échantillon de quelque chose de beaucoup plus grand que j'aime appeler l'espace des motifs.
C'est l'hypothèse terrible qui est répandue par les programmeurs néophytes partout dans le monde, des programmeurs qui pensent qu'ils peuvent écrire un programme simplement en assemblant des modèles de logiciels. Cela ne fonctionne pas de cette façon. S'il existe un tel "espace modèle", vous pouvez supposer que sa taille est effectivement infinie.
Les modèles de conception (au sens du GoF) n'ont qu'un seul but: pour compenser les déficiences du langage de programmation que vous utilisez.
Les modèles de conception ne sont ni universels ni complets. Si vous passez à un langage de programmation différent et plus expressif, la plupart des modèles du livre du GoF deviennent à la fois inutiles et indésirables.
Je pense que trois facteurs entrent en jeu ici.
Tout d'abord, un modèle est fondamentalement un peu plus que de donner un nom à un code qui implémente un "morceau" particulier de fonctionnalités. La seule façon dont ce nom fournit une valeur réelle est que si vous pouvez compter sur tout le monde sachant ce que signifie le nom, juste en utilisant le nom, ils comprennent immédiatement beaucoup de choses sur le code.
Les modèles n'ont jamais établi la masse critique dont ils avaient besoin pour y parvenir. C'est plutôt le contraire, l'AAMOF. Au cours des 20 (ou plus) années qui ont suivi la parution du livre du GoF, je suis pratiquement sûr de n'avoir pas vu jusqu'à une douzaine de conversations dans lesquelles toutes les personnes impliquées connaissaient vraiment suffisamment de modèles de conception pour leur permettre d'améliorer la communication.
Pour le dire un peu plus étrangement: les modèles de conception ont échoué spécifiquement parce qu'ils ont échoué.
Je pense que le deuxième facteur majeur est que, si quoi que ce soit, ils ont initialement nommé trop de modèles. Dans un bon nombre de cas, les différences entre les modèles sont suffisamment subtiles pour qu'il soit pratiquement impossible de dire avec certitude si une classe particulière correspond à un modèle ou à un autre (ou peut-être les deux - ou peut-être aucun).
L'intention était que vous puissiez parler de code à un niveau supérieur. Vous seriez en mesure d'étiqueter un morceau de code assez important en tant qu'implémentation d'un modèle particulier. En utilisant simplement ce nom prédéfini, tous ceux qui écoutent en savent généralement autant qu'ils se soucient de ce code, vous pouvez donc passer à la chose suivante.
La réalité tend à être presque le contraire. Disons que vous êtes en réunion et dites-leur que cette classe particulière est une façade. La moitié des personnes présentes à la réunion n'ont jamais su ou ont oublié depuis longtemps exactement ce que cela signifie. L'un d'eux vous demande de lui rappeler la ou les différences exactes entre une façade et, par exemple, un proxy. Oh, et le couple de personnes qui connaissent vraiment les modèles passent le reste de la réunion à débattre de la question de savoir si cela devrait vraiment être considéré comme une façade ou "juste" un adaptateur (avec ce type qui insiste toujours pour que cela lui semble être un proxy).
Étant donné que votre intention était vraiment de simplement dire: "ce code n'est pas très intéressant; passons à autre chose", en essayant d'utiliser le nom d'un modèle, cela n'a fait qu'ajouter de la distraction, pas de la valeur.
La plupart des modèles de conception ne traitent pas vraiment les parties intéressantes du code. Ils traitent de choses comme: "comment puis-je créer ces objets?", Et "comment puis-je amener cet objet à parler à celui-ci?" La mémorisation des noms de modèles pour ceux-ci (ainsi que les arguments susmentionnés sur les détails et autres) est simplement de mettre beaucoup d'énergie dans des choses que la plupart des programmeurs ne se soucient pas beaucoup.
Pour le dire légèrement différemment: les modèles traitent des choses qui sont les mêmes entre de nombreux programmes - mais ce qui rend vraiment un programme intéressant, c'est la façon dont il est différent des autres programmes.
Les modèles de conception ont échoué car:
Je pense que Paul Graham l'a dit le mieux:
Quand je vois des modèles dans mes programmes, je considère que c'est un signe de problème. La forme d'un programme ne devrait refléter que le problème qu'il doit résoudre. Toute autre régularité dans le code est un signe, pour moi au moins, que j'utilise des abstractions qui ne sont pas assez puissantes - souvent que je génère à la main les extensions d'une macro que je dois écrire.
Lorsque vous reconnaissez un modèle dans votre code, cela signifie que quelque chose se répète et vous devez utiliser une meilleure abstraction. Si vous n'avez pas une meilleure abstraction, vous utilisez le modèle comme solution de contournement. Parce que les nouveaux langages de programmation fournissent de meilleures abstractions, les modèles deviennent beaucoup moins utiles.
De même, les motifs simples sont souvent facilement résumés et les motifs complexes rarement reconnus.
Lorsqu'un modèle devient remplacé par une abstraction, cela ne signifie pas que le concept derrière le modèle disparaît, mais que le concept peut être écrit explicitement au lieu d'être indirect et qu'il n'est plus spécial par rapport à d'autres codes et qu'il ne devient plus reconnaissable comme un motif.
Bien que je sois principalement d'accord avec ce que les autres ont répondu ici, je pense personnellement que la raison principale d'un nombre non croissant de modèles est que les modèles perdent leur sens quand il y en a d'innombrables. Ce qui est bien avec ces quelques modèles, c'est qu'ils couvrent beaucoup de domaines problématiques de manière standard. Si vous vous concentriez sur un domaine de modèle sans fin, vous vous retrouveriez sans aucun modèle. C'est un peu comme "quelle est la longueur de la côte d'une île?". Si vous mesurez sur une carte, vous obtenez un nombre décent. Mais si vous essayez d'obtenir plus de précision et d'obtenir une résolution plus fine, vous constaterez que la longueur augmente de plus en plus à l'infini (ou incertitude; comment mesureriez-vous la frontière exacte avec les marées et au niveau atomique?).
Quelque chose qu'aucune des autres réponses ne mentionne et qui est également pertinent:
L'essor des langages typés dynamiquement.
Lorsque le livre est sorti pour la première fois, il y avait une discussion sérieuse selon laquelle Java était tout simplement trop lent pour faire un vrai travail. Maintenant Java est fréquemment utilisé sur des langages plus expressifs - parce que de sa vitesse. Peut-être que Ruby, Python, JavaScript et autres sont encore trop lents pour certaines classes importantes d'applications, mais en gros ils sont assez rapides pour la plupart des usages. Et JavaScript au moins est en fait de plus en plus rapide malgré le fait que plus de fonctionnalités sont incluses dans chaque version.
Le livre GoF d'origine avait les modèles à la fois dans Smalltalk et c ++, et si la mémoire est bonne, les modèles étaient toujours plus courts dans Smalltalk et parfois de manière significative. Certaines des fonctionnalités des modèles de conception classiques sont vraiment des moyens d'ajouter des fonctionnalités dynamiques à un système de type statique (comme la AbstractFactory déjà discutée, dans laquelle vous instanciez la classe correcte en fonction des données d'exécution). D'autres sont tellement plus courts dans les langues dynamiques qu'ils se fondent simplement dans une utilisation idiomatique de la langue elle-même.
Il est arrivé. Des dizaines sinon des centaines de livres ont été publiés dans ce qui ressemblait à une tentative de réduire l'ensemble de l'informatique aux modèles de conception, alors que les éditeurs et les auteurs tentaient de sauter (ou de créer) un autre mouvement. J'en ai une étagère. Jamais consulté depuis la première numérisation, et oui j'étais un surgeon, car il y avait peu ou rien là-dedans d'aucune utilité réelle ou qui n'était pas déjà bien connu (voir par exemple Type Object, qui n'est rien de plus que la troisième forme normale exprimée sur une dizaine de pages au lieu d'un paragraphe), et parce qu'évidemment, moins il y a de motifs, mieux c'est: un point qui échappait à la plupart des praticiens. En effet, lorsque j'ai posté une réfutation de Type Object, on m'a demandé de refondre mon texte comme modèle de conception. Histoire vraie. Ce qui montre également une autre lacune du projet: pas de mécanisme de révision, d'exclusion ou de rejet.
En fait, le GoF n'a pas réellement tenté d '"explorer en profondeur les modèles de conception". Au contraire, ils étaient engagés dans un projet beaucoup plus vaste: introduire un `` langage de modèle '' dans CS, avec tous ses arcanes de notation bizarres de Forces, Participants, etc., qui a simplement échoué, car il était fondamentalement mal conçu, tout en étant inutile.
Ce qu'ils ont fait accompli, ce qui était utile, était deux choses:
Un autre concept utile qui a émergé était le `` anti-modèle '', par exemple 'log and throw'. Le projet, comme de nombreuses manies en CS, a été déraillé par sa propre évangélisation et en étant adopté à tort comme une autre religion CS, et il a suivi la voie de la plupart de ces religions: utile en partie, mais certainement pas de solution miracle ((c ) Fred Brooks, 1965). Dommage que nous devions vraiment redécouvrir cela toutes les quelques années.
Il y avait/il y a plusieurs livres intitulés PLoP ( Pattern Languages of Program Design ) qui sont chacun une anthologie d'articles présentés à ne conférence annuelle .
En lisant les livres, j'ai trouvé que certains modèles étaient intéressants et nouveaux pour moi, certains d'entre eux des normes (par exemple, "demi-objet plus protocole").
Donc non, la collection du GoF n'était pas exhaustive et a inspiré/inspiré les gens à collecter/décrire/découvrir/inventer de nouveaux.
Les "seulement 12 modèles supplémentaires répertoriés dans l'article Wikipedia" ne sont probablement pas non plus une collection complète: c'est-à-dire qu'il y en a d'autres documentés ailleurs, par exemple dans les livres PLoP et peut-être ailleurs aussi.
Le livre Gang of Four (GoF) contient la plupart des modèles qu'un programmeur expérimenté dans un langage non fonctionnel a dans sa ceinture d'outils. C'est comme l'ensemble d'outils de base que tous les constructeurs savent utiliser. La principale contribution du livre a été de donner un nom bien défini aux modèles qui étaient couramment utilisés par les programmeurs les plus expérimentés à l'époque et donc faciliter la communication entre les programmeurs discutent des options de conception.
Vous vous attendez à ce qu'un électricien ait des outils qu'un constructeur normal ne possède pas, de même vous vous attendez à ce qu'un programmeur WPF connaisse les modèles de conception pour les "Propriétés de dépendance", ou un "programmeur SQL" pour connaître le modèle de conception pour utiliser des déclencheurs pour créer des données d'audit.
Cependant, nous ne les considérons pas comme des "modèles de conception" car ils ne sont utilisés qu'avec une seule technologie.
Certains autres livres de modèles de conception de modem sont "Refactoring, amélioration de la conception du code existant (Martin Fowler)" et "Clean Code: Un manuel de l'artisanat logiciel Agile (Robert C. Martin) " Ces deux livres présentent le contenu comme des transformations que vous apportez à votre code actuel, plutôt que comme" un design pré-réutilisable réutilisable ", mais ils sont tout autant des" modèles de conception ".
Voici une interview avec Erich Gamma où il réfléchit sur leur sélection de modèles et ce qu'ils changeraient aujourd'hui (enfin aujourd'hui il y a 10 ans, haha).
http://www.informit.com/articles/article.aspx?p=1404056
Larry: Comment refactoriseriez-vous les "Design Patterns"?
Erich: Nous avons fait cet exercice en 2005. Voici quelques notes de notre session. Nous avons constaté que les principes de conception orientée objet et la plupart des modèles n'ont pas changé depuis lors. Nous voulions changer la catégorisation, ajouter de nouveaux membres et également supprimer certains modèles. La plupart des discussions ont porté sur la modification de la catégorisation et en particulier sur les modèles à abandonner.
En discutant des modèles à abandonner, nous avons constaté que nous les aimons tous. (Pas vraiment - je suis en faveur de l'abandon de Singleton. Son utilisation est presque toujours une odeur de design.)
Voici donc quelques-uns des changements:
- L'interprète et la masselotte devraient être placés dans une catégorie distincte que nous avons appelée "Autre/Composé" car ce sont vraiment des bêtes différentes des autres modèles. La méthode d'usine serait généralisée à l'usine.
- Les catégories sont: Core, Creational, Peripheral et Other. Le but ici est de souligner les schémas importants et de les séparer des schémas les moins fréquemment utilisés.
- Les nouveaux membres sont: Null Object, Type Object, Dependency Injection et Extension Object/Interface (voir "Extension Object" dans Pattern Languages of Program Design 3, Addison-Wesley, 1997).
- Ce sont les catégories:
- Noyau: composite, stratégie, état, commande, itérateur, proxy, méthode de modèle, façade
- Créatif: Usine, prototype, constructeur, injection de dépendance
- Périphérique: usine abstraite, visiteur, décorateur, médiateur, objet type, objet nul, objet d'extension
- Autre: Flyweight, Interprète
Les modèles réels dans le livre sont parfois vraiment utiles, mais ce ne sont vraiment que des exemples d'un outil plus puissant que le livre vous donne: une compréhension approfondie du moment et de l'endroit où il est préférable de couper le code monolithique en parties indépendantes séparées et régulées par une interface .
Lorsque vous apprenez cette compétence, vous vous rendez compte que vous n'avez pas besoin de vous souvenir des détails exacts de chaque modèle, car vous pouvez toujours découper la solution que vous mettez en œuvre de la manière qui correspond le mieux à son objectif. L'idée d'écrire de plus en plus de modèles semble donc très académique et inutile.
Je m'attendais donc à ce que le nombre de modèles de conception connus et documentés augmente considérablement.
Cela ne s'est pas produit. Plus de 20 ans après la sortie du livre du GoF, seuls 12 modèles supplémentaires sont répertoriés dans l'article Wikipedia, dont la plupart sont beaucoup moins populaires que les originaux. (Je n'ai pas inclus les modèles de concurrence ici car ils couvrent un sujet spécifique.)
Le livre du GoF et Wikipedia ne sont guère la seule source de modèles de conception connus. Si vous recherchez simplement des "modèles de conception" sur Amazon.com, vous obtenez des centaines de livres (essayez ceci recherche ). Je suppose qu'ils ne répertorient que le modèle le plus connu dans le article Wikipedia .
Le problème n'est donc pas qu'il n'y a pas suffisamment de modèles de conception documentés. Au contraire, il y en a tellement que personne ne peut tous les mémoriser et la plupart des programmeurs n'en reconnaissent que quelques-uns. À ce stade, la grande promesse d'un langage de modèle commun s'effondre.