Il monkeypatching è considerato una buona pratica di programmazione?


15

Ho avuto l'impressione che il monkeypatching rientri più nella categoria hack veloce e sporca, piuttosto che nella pratica di programmazione standard. Mentre di tanto in tanto mi occupavo di risolvere piccoli problemi con le librerie di terze parti, la consideravo una soluzione temporanea e sottoponevo la patch corretta al progetto di terze parti.

Tuttavia, ho visto questa tecnica usata come "il modo normale" nei progetti tradizionali, ad esempio nel gevent.monkeymodulo di Gevent .

Il monkeypatching è diventato una pratica di programmazione normale, normale e accettabile?

Vedi anche: "Monkeypatching For Humans" di Jeff Atwood


13
Direi che qualcosa chiamato scimmia patching NON è considerato una buona pratica di programmazione. Senza nemmeno sapere di cosa si tratta, solo con il nome di esso.
littleadv,

Cosa succede se terze parti non vogliono fare la correzione di cui hai bisogno?

1
@ Thorbjørn: bella domanda, da un lato non mi piace il monkeypatching, dall'altro non mi piace l'idea di clonare progetti e mantenere patch locali se è solo un problema minore.
vartec,

1
@littleadv: ... allora chiamalo "hot fix" / "correzione al volo" o "runtime fix" e suona bene vero? ;) È tutto uguale.
dagnelies

3
javascript è praticamente costruito attorno al concetto
ZJR

Risposte:


19

No, ma a volte il monkeypatch è un male minore (rispetto al codice rotto :)). Le mie regole generali per i monkeypatch nel rubino sono:

  • ha davvero una buona ragione per la patch scimmia (l'aggiornamento rapido critico temporaneo è una buona ragione. Una buona formattazione del metodo to_s non lo è, a meno che tu non stia lavorando su ActiveSupport)

  • renderli il più trasparenti possibile: inserirli in una posizione specifica in codebase e file separati, scrivere la documentazione che descriva il motivo del monkeypatch (ecco un esempio ).

  • facile da rimuovere: la documentazione dovrebbe includere informazioni sulla rimozione e su cosa cercare. Molti monkeypatch sono temporanei, quindi dovrebbero essere facili da rimuovere.


11

Sì, il monkeypatching è molto utile!

In qualche modo, i nomi sembrano essere molto influenti sulla percezione delle persone. Chiamalo "monkeypatch" e suona male, chiamalo "hot fix" o "correzione al volo" e suona bene.

Indipendentemente da ciò, penso che la capacità di alterare metodi / attributi / funzioni in fase di esecuzione sia una cosa molto utile. Anche le persone javascript lo usano tutto il giorno senza forse saperlo.

Per esempio:

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

Questa semplice riga illustra il fatto che si modifica il comportamento del pulsante. È stato progettato in questo modo. Allo stesso modo, potresti alterare ogni altra funzione ma sarebbe sciocco farlo.

Ora, per la questione di consegnare le patch in quel modo ... beh ... perché no. Devi solo scaricare una piccola patch invece di una grande versione. Cavolo, potresti persino patchare un server senza fermarlo, fantastico! E poi, un giorno, potresti anche recuperare l'ultima versione per un aggiornamento più grande. Giusto. Quindi sì, io voto per "patch di runtime" come una buona cosa.

È interessante notare che alcune lingue come Erlang sono state persino costruite attorno a questo concetto. La possibilità di aggiornare un server al volo.

Certo, alla fine, e come tutto il resto, dipende da come lo usi. Puoi fare cose OO meravigliose e di merda, è lo stesso.

MODIFICARE:

Consentitemi di aggiungere una distinzione tra maiuscole e minuscole, sia che stiate correggendo la vostra libreria o quella di terzi .

... fondamentalmente, ciò che fai con una tale patch è correggere un bug della tua libreria o di una terza parte . In entrambi i casi è utile. Per conto tuo, ti consente di fornire una soluzione al volo. Per un terzo, o aspetti (diversi mesi?) Fino a quando non lo risolvono da soli o lo fai ora da solo. (puoi comunque inviare loro la patch, in modo che la riparino dalla loro parte). Quando rilasciano la loro prossima versione lib con il problema risolto, potete comunque, se volete aggiornare la libreria e rimuovere la patch dalla vostra parte.

Ora, ovviamente, se usi una patch per alterare il comportamento di una lib e alienarne lo scopo / il modo di lavorare, ovviamente questa è una ricetta per il disastro. Perfino una scimmia lo vedrebbe ... beh, spero. ;)


1
Nessuno dice che non sia utile. Tuttavia, non è una buona pratica in generale. E "hotfix" e "on-the-fly fix" non suonano meglio per me.
Lukas Stejskal,

1
Bene, trovo molto utile la capacità di alterare il comportamento di un'applicazione al volo, ancora di più se è grande. Cavolo, potresti anche avere il codice che memorizza il vecchio metodo come backup e un comando per il rollback automatico su richiesta! Le possibilità sono enormi!
dagnelies

Sono d'accordo che sia una funzionalità potente e utile. Ma anche molto pericoloso (in particolare in Ruby), quindi dovrebbe essere usato con estrema cautela (in particolare per la modifica di librerie standard e di terze parti). Hai mai provato a mantenere l'applicazione in base a diverse librerie di terze parti con monkeypatch? Una ricetta per il disastro ogni volta che provi ad aggiornare alcune librerie.
Lukas Stejskal,

1
Sì, sono d'accordo, se usi queste patch con noncuranza, in modo non intenzionale o in caso di abuso, possono rapidamente diventare disordinate. Come se tu potessi abusare di qualsiasi concetto o rovinare qualcosa. Tuttavia, altrimenti, se sono ben organizzati e trasparenti e fluiscono tutti nella prossima versione grande, mi sembra pulito. ... tuttavia, non ho esperienza con le librerie ruby ​​che sono pesantemente patchate.
Dagnelies,

... ho aggiunto alcuni commenti su quest'ultimo caso.
Dagnelies,

8

Credo che tutte le patch siano intrinsecamente rischiose a causa della loro natura runtime e dell'incapacità di essere colte al momento della progettazione.

Accettano eccezioni di runtime e richiedono debugger e watch complessi solo per seguire.

Sono usati quando le persone GUARNANO le lezioni, e quindi l'eredità è impossibile. Tuttavia, ci sono modi migliori per estendere gli oggetti senza danneggiarli.

I miei due centesimi


4

Il patching in generale dovrebbe essere l'ultima risorsa, il patching delle scimmie ancora di più. Il problema riguarda principalmente la manutenibilità.

Molto tempo fa, il mio kernel Linux aveva 3 patch separate applicate ad esso, necessarie per il mio driver della scheda video e due applicazioni proprietarie che avevo. Due di loro hanno avuto cambiamenti contrastanti, il che significava che avevo bisogno di una quarta patch per risolvere le differenze tra loro. Ora, ogni volta che veniva risolto un problema di sicurezza nel kernel upstream, o dovevo aspettare che i venditori di quelle 3 patch rilasciassero un aggiornamento alla nuova versione del kernel, che impiegava da uno a sei mesi, oppure dovevo mantenere manualmente l'upstream patch di sicurezza fino a quando gli altri venditori di patch non hanno raggiunto.

Dopo alcuni anni, i venditori sono riusciti a essere inclusi nel sorgente del kernel upstream e sono stato in grado di fermare l'atto di bilanciamento, ma puoi vedere che casino era nel frattempo. Non infliggere questo ai tuoi programmatori a meno che non sia necessario.


3

No. Non è una tecnica standard per lo sviluppo del software. Resta una soluzione alternativa per risolvere un problema acuto e presenta chiari inconvenienti. Mi viene in mente la violazione del principio di sostituzione di Liskov . Il patching delle scimmie rende molto più difficile ragionare sui programmi. Per i tuoi programmi devi posizionare il codice a cui appartiene. Per le librerie di terze parti vivrai sempre in pericolo, che la tua patch non funzionerà con la prossima versione della libreria.

Ovviamente il patching delle scimmie è utile se sai cosa stai facendo e non hai il tempo di implementare una soluzione SOLID . Ma non dovresti mai considerare questa una tecnica standard e costruire patch scimmia su patch scimmia.

A proposito, hai mai scritto un test unitario per una patch di scimmia?


Non penso che tu possa applicare LSP qui. Ha una definizione molto specifica relativa ai sottotipi.
Konrad Rudolph,

@KonradRudolph La scimmia che corregge un oggetto cambia il suo tipo. Nelle lingue tipizzate dinamicamente ogni tipo t con la stessa interfaccia del tipo u è un sottotipo di u. Se cammina come un'anatra ...
scarfridge

"... cambia tipo" - abbastanza giusto. Ha senso.
Konrad Rudolph,

RE "Non è una tecnica standard per lo sviluppo del software.", Sembra essere fatto sempre * e nelle principali librerie "in Python per i test.
Tommy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.