Wird Monkeypatching als gute Programmierpraxis angesehen?

15

Ich hatte den Eindruck, dass Monkeypatching eher in der Kategorie der schnellen und schmutzigen Hacks als in der üblichen guten Programmierpraxis liegt. Obwohl ich von Zeit zu Zeit kleinere Probleme mit Bibliotheken von Drittanbietern behoben hatte, hielt ich es für eine vorübergehende Behebung und übermittelte dem Drittanbieterprojekt den richtigen Patch.

Ich habe diese Technik jedoch als "den normalen Weg" in Mainstream-Projekten gesehen, zum Beispiel in Gevents gevent.monkeyModul .

Hat sich Monkeypatching als gängige, normale und akzeptable Programmierpraxis etabliert?

Siehe auch: "Monkeypatching For Humans" von Jeff Atwood

vartec
quelle
13
Ich würde sagen, dass etwas namens Affen- Patching NICHT als gute Programmierpraxis angesehen wird. Ohne zu wissen, was es ist, nur beim Namen.
Littleadv
Was ist, wenn Drittanbieter das benötigte Update nicht ausführen möchten?
1
@ Thorbjørn: Gute Frage, einerseits mag ich kein Monkeypatching, andererseits mag ich keine Idee, ein Projekt zu klonen und lokale Patches beizubehalten, wenn es nur ein kleines Problem ist.
Vartec
1
@littleadv: ... dann nenne es "hot fix" / "on-the-fly fix" oder "runtime fix" und es hört sich gut an, oder? ;) Es ist alles das Gleiche.
Dagnelies
3
Javascript ist so ziemlich rund um das Konzept aufgebaut
ZJR

Antworten:

19

Nein, aber manchmal ist Monkeypatch ein geringeres Übel (als wenn man Code gebrochen hat :)). Meine allgemeinen Regeln für Monkeypatches in Ruby sind:

  • Ich habe einen guten Grund für den Affen-Patch (ein vorübergehender kritischer Hotfix ist ein guter Grund. Eine gute Formatierung der to_s-Methode ist dies nicht, es sei denn, Sie arbeiten an ActiveSupport.)

  • Machen Sie sie so transparent wie möglich: Platzieren Sie sie an einer bestimmten Stelle in der Codebasis und trennen Sie die Dateien. Schreiben Sie eine Dokumentation, in der der Grund für Monkeypatch beschrieben wird (hier ein Beispiel ).

  • Leicht zu entfernen - Die Dokumentation sollte Informationen zum Entfernen und zu den zu beachtenden Elementen enthalten. Viele Monkeypatches sind temporär, daher sollten sie leicht zu entfernen sein.

Lukas Stejskal
quelle
11

Ja, Monkeypatching ist sehr nützlich!

Irgendwie scheinen Namen einen großen Einfluss auf die Wahrnehmung der Menschen zu haben. Nennen Sie es "Monkeypatch" und es klingt schlecht, nennen Sie es "Hot Fix" oder "On-the-Fly Fix" und es klingt gut.

Unabhängig davon halte ich die Möglichkeit, Methoden / Attribute / Funktionen zur Laufzeit zu ändern, für eine sehr nützliche Sache. Selbst Javascript wird den ganzen Tag benutzt, ohne es zu wissen.

Zum Beispiel:

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

Diese einfache Linie zeigt, dass Sie das Verhalten der Schaltfläche ändern. Es wurde so konzipiert. Ebenso könnten Sie jede andere Funktion ändern, aber es wäre dumm, dies zu tun.

Nun zu der Frage, wie Patches auf diese Weise geliefert werden sollen ... na ja ... warum nicht. Sie müssen nur einen kleinen Patch anstelle einer großen Version herunterladen. Du könntest sogar einen Server patchen, ohne ihn anzuhalten, großartig! Und dann könnten Sie eines Tages auch die neueste Version für ein größeres Update abrufen. Meinetwegen. Also ja, ich stimme für "Laufzeit-Patches" als eine gute Sache.

Interessanterweise wurden einige Sprachen wie Erlang sogar um dieses Konzept herum aufgebaut. Die Fähigkeit, einen Server im laufenden Betrieb zu aktualisieren.

Natürlich ist es am Ende und wie bei allem anderen auch eine Frage der Verwendung. Du kannst wundervolle OO-Sachen machen und eine Scheiße, es ist alles das Gleiche.

BEARBEITEN:

Lassen Sie mich einen Unterschied zwischen Groß- und Kleinschreibung machen, unabhängig davon, ob Sie Ihre eigene Bibliothek oder eine von Drittanbietern patchen .

... im Grunde, was mit Ihnen tun ein solcher Patch einen Fehler von sich Festsetzung Ihre eigenen oder einen Dritten Bibliothek. In beiden Fällen ist es nützlich. Auf eigene Faust können Sie eine schnelle Fehlerbehebung durchführen. Für einen Drittanbieter warten Sie entweder (mehrere Monate?), Bis er es selbst repariert, oder Sie tun es jetzt selbst. (Sie können ihnen den Patch trotzdem übermitteln, damit sie ihn auf ihrer Seite reparieren). Wenn sie ihre nächste lib - Version mit dem Problem behebt Release können Sie noch, wenn Sie die Bibliothek aktualisieren und den Patch auf Ihrer Seite entfernen.

Wenn Sie nun ein Patch verwenden, um das Verhalten einer Bibliothek zu ändern und ihren Zweck / ihre Arbeitsweise zu entfremden, dann ist das natürlich ein Rezept für eine Katastrophe. Sogar ein Affe würde das sehen ... nun, ich hoffe. ;)

dagnelies
quelle
1
Niemand sagt, dass es nicht nützlich ist. Im Allgemeinen ist dies jedoch keine gute Praxis. Und "Hotfix" und "On-the-Fly-Fix" klingen für mich nicht besser.
Lukas Stejskal
1
Nun, ich finde die Möglichkeit, das Verhalten einer Anwendung im laufenden Betrieb zu ändern, sehr nützlich, umso mehr, wenn es sich um eine große Anwendung handelt. Heck, Sie könnten sogar den Code haben, der die alte Methode als Backup und einen Befehl zum automatischen Rollback bei Bedarf speichert! Die Möglichkeiten sind enorm!
Dagnelies
Ich bin damit einverstanden, dass es eine leistungsstarke und nützliche Funktion ist. Aber auch sehr gefährlich (insbesondere in Ruby), daher sollte es mit äußerster Vorsicht verwendet werden (insbesondere zum Ändern von Standard- und Drittanbieter-Bibliotheken). Haben Sie jemals versucht, die Anwendung abhängig von mehreren Bibliotheken von Drittanbietern mit Monkeypatch zu warten? Ein Rezept für eine Katastrophe, wenn Sie versuchen, eine Bibliothek zu aktualisieren.
Lukas Stejskal
1
Ja, ich bin einverstanden, wenn Sie diese Patches unachtsam, unbeabsichtigt oder missbräuchlich verwenden, kann es schnell chaotisch werden. Als ob Sie jedes Konzept missbrauchen oder mit irgendetwas herumspielen könnten. Wenn sie jedoch gut organisiert und transparent sind und alle in der nächsten großen Veröffentlichung einfließen, sieht es für mich sauber aus. ... Ich habe jedoch keine Erfahrung mit Ruby-Bibliotheken, die stark gepatcht sind.
Dagnelies
... Ich habe einige Kommentare zum letzteren Fall hinzugefügt.
Dagnelies
8

Ich glaube, dass alle Patches aufgrund ihres Laufzeitcharakters und der Unfähigkeit, zur Entwurfszeit abgefangen zu werden, von Natur aus riskant sind.

Sie begrüßen Laufzeitausnahmen und erfordern komplexe Debugger und Watches, die nur folgen müssen.

Sie werden verwendet, wenn People SEAL-Klassen verwendet werden, sodass eine Vererbung nicht möglich ist. Es gibt jedoch bessere Möglichkeiten, Objekte zu erweitern, ohne sie zu beschädigen.

Meine zwei Cent

Mickey Perlstein
quelle
4

Das Patchen sollte im Allgemeinen das letzte Mittel sein, das Patchen von Affen noch mehr. Das Problem ist in erster Linie die Wartbarkeit.

Vor langer Zeit wurden auf meinem Linux-Kernel drei separate Patches angewendet, die für meinen Grafikkartentreiber und zwei proprietäre Anwendungen erforderlich waren. Zwei von ihnen hatten widersprüchliche Änderungen, was bedeutete, dass ich einen vierten Patch benötigte, um die Unterschiede zwischen ihnen zu beheben. Wann immer ein Sicherheitsproblem im Upstream-Kernel behoben wurde, musste ich entweder warten, bis die Hersteller dieser 3 Patches ein Update für die neue Kernel-Version herausbrachten, was ein bis sechs Monate dauerte, oder ich musste den Upstream manuell warten Sicherheits-Patches, bis die anderen Patch-Anbieter aufgeschlossen haben.

Nach ein paar Jahren gelang es den Anbietern, in die Quelle des Upstream-Kernels aufgenommen zu werden, und ich konnte den Spagat stoppen, aber Sie können sehen, was für ein Durcheinander es in der Zwischenzeit war. Verursachen Sie das nicht bei Ihren Programmierern, es sei denn, Sie müssen es tun.

Karl Bielefeldt
quelle
3

Nein, es ist keine Standardtechnik für die Softwareentwicklung. Es bleibt eine Problemumgehung, um ein akutes Problem zu lösen, und weist deutliche Nachteile auf. Man denkt an eine Verletzung des Liskov-Substitutionsprinzips . Das Patchen mit Affen erschwert das Nachdenken über Programme erheblich. Für Ihre eigenen Programme sollten Sie den Code dort platzieren, wo er hingehört. Für Drittanbieter-Bibliotheken besteht immer die Gefahr, dass Ihr Patch mit der nächsten Version der Bibliothek nicht funktioniert.

Das Patchen von Affen ist natürlich nützlich, wenn Sie wissen, was Sie tun, und keine Zeit haben, eine SOLID- Lösung zu implementieren . Sie sollten dies jedoch niemals als Standardtechnik betrachten und Affen-Patch auf Affen-Patch aufbauen.

Übrigens, haben Sie jemals einen Unit-Test für einen Affen-Patch geschrieben?

Narbenkühlschrank
quelle
Ich glaube nicht, dass Sie hier LSP anwenden können. Es hat eine sehr spezifische Definition in Bezug auf Subtypen.
Konrad Rudolph
@KonradRudolph Affe beim Patchen eines Objekts ändert seinen Typ. In dynamisch typisierten Sprachen ist jeder Typ t mit der gleichen Schnittstelle wie der Typ u ein Subtyp von u. Wenn es wie eine Ente geht ...
Narbenkühlschrank
„… Ändert seinen Typ“ - fair genug. Macht Sinn.
Konrad Rudolph
RE "Es ist keine Standardtechnik für die Softwareentwicklung.", Scheint es die ganze Zeit und in großen Bibliotheken in Python zum Testen durchgeführt zu werden.
Tommy