Le monkeypatching est-il considéré comme une bonne pratique de programmation?

15

J'ai été sous l'impression que le monkeypatching est plus dans la catégorie de piratage rapide et sale, plutôt que de bonnes pratiques de programmation standard. Bien que j'aie utilisé de temps en temps pour résoudre des problèmes mineurs avec des bibliothèques tierces, je l'ai considéré comme un correctif temporaire et je soumettais le correctif approprié au projet tiers.

Cependant, j'ai vu cette technique utilisée comme "la voie normale" dans les projets traditionnels, par exemple dans le gevent.monkeymodule de Gevent .

Le monkeypatching est-il devenu une pratique de programmation courante, normale et acceptable?

Voir aussi: "Monkeypatching For Humans" par Jeff Atwood

vartec
la source
13
Je dirais que quelque chose nommé patch de singe n'est PAS considéré comme une bonne pratique de programmation. Sans même savoir ce que c'est, juste par son nom.
littleadv
Que se passe-t-il si un tiers ne souhaite pas effectuer la correction dont vous avez besoin?
1
@ Thorbjørn: bonne question, d'une part, je n'aime pas le monkeypatching, d'autre part, je n'aime pas trop l'idée de cloner un projet et de conserver des correctifs locaux si c'est juste un problème mineur.
vartec
1
@littleadv: ... alors appelez-le "hot fix" / "on-the-fly fix" ou "runtime fix" et ça sonne bien non? ;) C'est tout pareil.
dagnelies
3
javascript est à peu près construit autour du concept
ZJR

Réponses:

19

Non, mais parfois monkeypatch est un moindre mal (que d'avoir du code cassé :)). Mes règles générales pour les singes en rubis sont:

  • avoir une très bonne raison pour le patch de singe (le correctif critique temporaire est une bonne raison. Le bon formatage de la méthode to_s ne l'est pas, sauf si vous travaillez sur ActiveSupport)

  • les rendre aussi transparents que possible: mettez-les à un endroit spécifique dans la base de code et des fichiers séparés, rédigez une documentation décrivant la raison de monkeypatch (voici un exemple ).

  • facile à retirer - la documentation doit inclure des informations sur la suppression et les éléments à surveiller. Beaucoup de singes sont temporaires, ils devraient donc être faciles à retirer.

Lukas Stejskal
la source
11

Oui, le monkeypatching est très utile!

D'une manière ou d'une autre, les noms semblent fortement influencer la perception des gens. Appelez-le "monkeypatch" et ça sonne mal, appelez-le "hot fix" ou "fix à la volée" et ça sonne bien.

Indépendamment de cela, je pense que la possibilité de modifier les méthodes / attributs / fonctions à l'exécution est une chose très utile. Même les gens de javascript l'utilisent toute la journée sans le savoir.

Par exemple:

button.onclick = function(e) { ...}

Cette ligne simple illustre le fait que vous modifiez le comportement du bouton. Il a été conçu de cette façon. De même, vous pouvez modifier toutes les autres fonctions, mais ce serait idiot de le faire.

Maintenant, pour la question de fournir des correctifs de cette façon ... eh bien ... pourquoi pas. Il vous suffit de télécharger un petit patch au lieu d'une grosse version. Heck, vous pouvez même patcher un serveur sans l'arrêter, c'est parfait! Et puis, un jour, vous pourrez également récupérer la dernière version pour une mise à jour plus importante. C'est suffisant. Alors oui, je vote pour les "correctifs d'exécution" comme une bonne chose.

Chose intéressante, certaines langues comme Erlang ont même été construites autour de ce concept. La possibilité de mettre à jour un serveur à la volée.

Bien sûr, à la fin, et comme pour tout le reste, c'est une question de comment vous l'utilisez. Vous pouvez faire de merveilleuses choses OO et des merdes, c'est tout de même.

ÉDITER:

Permettez-moi d'ajouter une distinction de cas, que vous corrigiez votre propre bibliothèque ou une bibliothèque tierce .

... en gros, ce que vous faites avec un tel correctif, c'est de corriger votre propre bogue ou une bibliothèque tierce . Dans les deux cas, c'est utile. Pour votre propre compte, il vous permet de fournir un correctif à la volée. Pour un tiers, soit vous attendez (plusieurs mois?) Jusqu'à ce qu'ils le réparent d'eux-mêmes, soit vous le faites maintenant par vous-même. (vous pouvez toujours leur soumettre le patch, afin qu'ils le fixent de leur côté). Quand ils publieront leur prochaine version de lib avec le problème résolu, vous pouvez toujours, si vous voulez mettre à jour la bibliothèque et supprimer le patch de votre côté.

Maintenant, bien sûr, si vous utilisez un patch pour modifier le comportement d'une bibliothèque et aliéner son but / sa façon de travailler, alors c'est évidemment une recette pour un désastre. Même un singe verrait ça ... enfin, j'espère. ;)

dagnelies
la source
1
Personne ne dit que ce n'est pas utile. Cependant, ce n'est pas une bonne pratique en général. Et "correctif" et "correctif à la volée" ne me semblent pas meilleurs.
Lukas Stejskal
1
Eh bien, je trouve la capacité de modifier le comportement d'une application à la volée très utile, encore plus si elle est grande. Heck, vous pourriez même avoir le code stockant l'ancienne méthode comme sauvegarde et une commande pour restaurer automatiquement à la demande! Les possibilités sont énormes!
dagnelies
Je suis d'accord que c'est une fonctionnalité puissante et utile. Mais aussi très dangereux (en particulier en Ruby), il doit donc être utilisé avec une extrême prudence (en particulier pour la modification des bibliothèques standard et tierces). Avez-vous déjà essayé de maintenir l'application en fonction de plusieurs bibliothèques tierces monkeypatchées? Une recette pour un désastre chaque fois que vous essayez de mettre à jour une bibliothèque.
Lukas Stejskal
1
Oui, je suis d'accord, si vous utilisez ces correctifs de manière imprudente, de manière non intentionnelle ou en abusez, cela peut rapidement devenir désordonné. Comme si vous pouviez abuser de n'importe quel concept ou gâcher quoi que ce soit. Cependant, sinon, s'ils sont bien organisés et transparents, et qu'ils coulent tous dans la prochaine grande version, cela me semble propre. ... cependant, je n'ai aucune expérience avec les bibliothèques ruby ​​qui sont fortement corrigées.
dagnelies
... J'ai ajouté quelques commentaires sur ce dernier cas.
dagnelies
8

Je crois que tous les correctifs sont intrinsèquement risqués en raison de leur nature au moment de l'exécution et de leur incapacité à être détectés au moment de la conception.

Ils acceptent les exceptions d'exécution et nécessitent des débogueurs et des surveillances complexes juste pour suivre.

Ils sont utilisés lorsque les gens SEAL classes, et donc l'héritage est impossible. Cependant, il existe de meilleures façons d'étendre des objets sans les endommager.

Mes deux centimes

Mickey Perlstein
la source
4

Le patch en général devrait être un dernier recours, le patch du singe encore plus. Le problème est principalement un problème de maintenabilité.

Il y a longtemps, mon noyau Linux avait appliqué 3 correctifs distincts, nécessaires pour mon pilote de carte vidéo et deux applications propriétaires que j'avais. Deux d'entre eux ont eu des changements contradictoires, ce qui signifiait que j'avais besoin d'un quatrième patch pour résoudre les différences entre eux. Maintenant, chaque fois qu'un problème de sécurité était résolu dans le noyau en amont, je devais attendre que les fournisseurs de ces 3 correctifs publient une mise à jour de la nouvelle version du noyau, ce qui prenait de un à six mois, ou je devais maintenir manuellement l'amont correctifs de sécurité jusqu'à ce que les autres fournisseurs de correctifs rattrapent leur retard.

Après quelques années, les fournisseurs ont réussi à être inclus dans la source du noyau en amont, et j'ai pu arrêter l'acte d'équilibrage, mais vous pouvez voir quel gâchis c'était entre-temps. N'infligez pas cela à vos programmeurs, sauf si vous le devez.

Karl Bielefeldt
la source
3

Non. Ce n'est pas une technique standard pour le développement de logiciels. Il reste une solution de contournement pour résoudre un problème aigu et présente des inconvénients évidents. La violation du principe de substitution de Liskov vient à l'esprit. L'application de patches de singe complique considérablement la réflexion sur les programmes. Pour vos propres programmes, vous devez placer le code à sa place. Pour les bibliothèques tierces, vous vivrez toujours le danger que votre patch ne fonctionne pas avec la prochaine version de la bibliothèque.

Bien sûr, l'application de patches de singe est utile si vous savez ce que vous faites et que vous n'avez pas le temps de mettre en œuvre une solution SOLIDE . Mais vous ne devriez jamais considérer cela comme une technique standard et construire un patch de singe sur un patch de singe.

BTW, avez-vous déjà écrit un test unitaire pour un patch de singe?

écharpe
la source
Je ne pense pas que vous puissiez appliquer le LSP ici. Il a une définition très spécifique concernant les sous-types.
Konrad Rudolph
@KonradRudolph Monkey corrigeant un objet change son type. Dans les langues typées dynamiquement, chaque type t avec la même interface que le type u est un sous-type de u. S'il marche comme un canard ...
scarfridge
«… Change de type» - assez juste. Logique.
Konrad Rudolph
RE "Ce n'est pas une technique standard pour le développement de logiciels.", Cela semble être fait * tout le temps et dans les principales bibliothèques "en Python pour les tests.
Tommy