Eu tenho a impressão de que o monkeypatching é mais uma categoria de hack rápido e sujo, em vez de boas práticas de programação padrão. Embora eu tenha usado de tempos em tempos para corrigir pequenos problemas com bibliotecas de terceiros, considerei uma correção temporária e enviaria o patch adequado ao projeto de terceiros.
No entanto, eu vi essa técnica usada como "o caminho normal" em projetos convencionais, por exemplo, no gevent.monkey
módulo de Gevent .
O monkeypatching tornou-se prática de programação convencional, normal e aceitável?
Veja também: "Monkeypatching For Humans", de Jeff Atwood
Respostas:
Não, mas às vezes o monkeypatch é um mal menor (do que ter código quebrado :)). Minhas regras gerais para monkeypatches em ruby são:
tenha um bom motivo para o patch do macaco (o hotfix crítico temporário é um bom motivo. A boa formatação do método to_s não é, a menos que você esteja trabalhando no ActiveSupport)
torne-os o mais transparentes possível: coloque-os em um local específico na base de código e em arquivos separados, escreva documentação descrevendo o motivo do monkeypatch (veja um exemplo ).
fácil de remover - a documentação deve incluir informações sobre remoção e o que observar. Muitos monkeypatches são temporários, portanto devem ser fáceis de remover.
fonte
Sim, o monkeypatching é muito útil!
De alguma forma, os nomes parecem ser altamente influentes na percepção das pessoas. Chame de "monkeypatch" e soa mal, chame de "hot fix" ou "on-the-fly fix" e soa bem.
Independentemente disso, acho que a capacidade de alterar métodos / atributos / funções em tempo de execução é uma coisa muito útil. Até as pessoas que usam javascript usam o dia todo, talvez sem saber.
Por exemplo:
Esta linha simples ilustra o fato de que você altera o comportamento do botão. Foi projetado dessa maneira. Da mesma forma, você pode alterar todas as outras funções, mas seria tolo fazê-lo.
Agora, para a questão de entregar patches dessa maneira ... bem ... por que não. Você só precisa baixar um pequeno patch em vez de um grande lançamento. Caramba, você pode até corrigir um servidor sem parar, ótimo! E então, um dia, você também pode buscar a versão mais recente para obter uma atualização maior. Justo. Então, sim, voto por "patches de tempo de execução" como uma coisa boa.
Curiosamente, algumas línguas como Erlang foram construídas em torno desse conceito. A capacidade de atualizar um servidor em tempo real.
É claro que, no final, e como em todo o resto, é uma questão de como você o usa. Você pode fazer coisas maravilhosas de OO e uma merda, é tudo a mesma coisa.
EDITAR:
Deixe-me adicionar uma distinção entre maiúsculas e minúsculas, se você está corrigindo sua própria biblioteca ou uma biblioteca de terceiros .
... basicamente, o que você faz com esse patch é consertar um bug próprio ou de uma biblioteca de terceiros . Em ambos os casos, é útil. Para você, ele permite que você forneça uma correção em tempo real. Para um terceiro, você espera (vários meses?) Até que eles o consertem por conta própria ou você o faça agora por conta própria. (você ainda pode enviar o patch para eles, para que o consertem). Quando eles liberam sua próxima versão lib com o problema corrigido, você ainda pode, se você quiser atualizar a biblioteca e remover o patch do seu lado.
Agora, é claro, se você usa um patch para alterar o comportamento de uma lib e alienar seu propósito / maneira de trabalhar, então obviamente isso é uma receita para o desastre. Até um macaco veria isso ... bem, espero. ;)
fonte
Acredito que todos os patches são inerentemente arriscados devido à sua natureza em tempo de execução e à incapacidade de serem capturados no tempo de design.
Eles aceitam exceções de tempo de execução e exigem depuradores e relógios complexos apenas para serem seguidos.
Eles são usados quando as pessoas SEAL classificam e, portanto, a herança é impossível. No entanto, existem maneiras melhores de estender objetos sem danificá-los.
Meus dois centavos
fonte
A aplicação de patches em geral deve ser o último recurso, a aplicação de patches de macaco ainda mais. O problema é principalmente de manutenção.
Há muito tempo, meu kernel do linux tinha 3 patches separados, necessários para o driver da minha placa de vídeo e dois aplicativos proprietários que eu tinha. Dois deles tiveram alterações conflitantes, o que significava que eu precisava de um quarto patch para resolver as diferenças entre eles. Agora, sempre que um problema de segurança era corrigido no kernel upstream, eu precisava esperar pelos fornecedores desses 3 patches para lançar uma atualização para a nova versão do kernel, que levava de um a seis meses, ou eu tinha que manter manualmente o upstream patches de segurança até que os outros fornecedores de patches os alcançassem.
Depois de alguns anos, os fornecedores conseguiram ser incluídos na fonte do kernel upstream, e eu pude interromper o ato de balanceamento, mas você pode ver o que era uma bagunça nesse meio tempo. Não imponha isso aos seus programadores, a menos que você precise.
fonte
Não. Não é uma técnica padrão para desenvolvimento de software. Continua sendo uma solução alternativa para resolver um problema agudo e possui desvantagens claras. A violação do princípio da substituição de Liskov vem à mente. A aplicação de patches de macaco dificulta seriamente a discussão sobre os programas. Para seus próprios programas, você deve colocar o código onde ele pertence. Para bibliotecas de terceiros, você sempre estará em perigo, pois seu patch não funcionará com a próxima versão da lib.
É claro que a aplicação de patches de macaco é útil se você souber o que está fazendo e não tiver tempo para implementar uma solução SOLID . Mas você nunca deve considerar isso uma técnica padrão e criar um patch de macacos em cima de um macacão.
BTW, você já escreveu um teste de unidade para um patch de macaco?
fonte