web-dev-qa-db-ja.com

モンキーパッチはプログラミングの良い習慣と考えられていますか?

monkeypatching は、標準的で優れたプログラミング手法というよりも、迅速で汚いハッキングのカテゴリに属しているという印象を受けました。私は時々サードパーティのライブラリのマイナーな問題を修正するために使用しましたが、それは一時的な修正であると考え、適切なパッチをサードパーティのプロジェクトに提出しました。

ただし、この手法が主流のプロジェクト、たとえばGeventの gevent.monkeyモジュール

モンキーパッチは、主流の、通常の、許容できるプログラミング手法になりましたか?

参照: "Monkeypatching For Humans"by Jeff Atwood

15
vartec

いいえ、ただしmonkeypatchは、(コードが壊れているよりも)それほど危険ではありません。 Ruby)でのモンキーパッチに関する私の一般的なルールは次のとおりです。

  • モンキーパッチに本当に良い理由がある(一時的な重要な修正プログラムが良い理由です。ActiveSupportで作業しているのでない限り、to_sメソッドの適切なフォーマットは違います)

  • それらを可能な限り透過的にします。コードベースの特定の場所に置き、ファイルを分離し、モンキーパッチの理由を説明するドキュメントを書きます(ここに があります)。

  • 簡単に削除-削除に関する情報と注意事項をドキュメントに含める必要があります。多くのモンキーパッチは一時的なものなので、簡単に取り除くことができます。

19
Lukas Stejskal

はい、モンキーパッチは非常に便利です!

どういうわけか、名前は人々の知覚に非常に影響力があるようです。それを「monkeypatch」と呼んで、それは悪いように聞こえ、それを「ホットフィックス」または「オンザフライ修正」と呼んで、それはいい音です。

それとは別に、実行時にメソッド/属性/関数を変更する機能は非常に便利だと思います。 JavaScriptの人でさえ、おそらく知らないうちに1日中使用しています。

例えば:

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

この単純な線は、ボタンの動作を変更するという事実を示しています。それはそのように設計されました。同様に、他のすべての機能を変更することもできますが、そうするのはばかげています。

さて、パッチをそのように配信することについての質問については...まあ...なぜそうではありませんか大きなリリースの代わりに小さなパッチをダウンロードする必要があります。サーバーを停止せずにパッチを適用することもできます。そして、ある日、より大きなアップデートのために最新のリリースを取得することもできました。けっこうだ。ですから、私は「ランタイムパッチ」に賛成票を投じます。

興味深いことに、Erlangなどの一部の言語はこの概念を中心に構築されていました。サーバーをその場で更新する機能。

もちろん、結局のところ、他のすべてと同じように、それをどのように使用するかが問題になります。あなたは素晴らしいOOものとくだらないものを作ることができます、それはすべて同じです。

編集:

独自のライブラリにパッチを当てているのか、サードパーティ1つ。

...基本的に、そのようなパッチで行うことは、自分のバグまたはサードパーティのバグを修正することですライブラリ。どちらの場合も便利です。独自の方法で、修正をオンザフライで提供できます。サードパーティの場合は、彼らが自分で修正するまで(数か月?)待つか、自分で修正します。 (あなたはまだ彼らにパッチを提出して、彼らが彼らの側でそれを修正するようにすることができます)。問題が修正された次のlibバージョンがリリースされた場合でも、必要に応じてライブラリを更新して、パッチを削除できます。

もちろん、もちろん、パッチを使用してlibの動作を変更し、libの目的/動作方法を疎外する場合、それは明らかに災害のレシピです。猿でさえそれを見るだろう...まあ、私は願っています。 ;)

11
dagnelies

すべてのパッチは、その実行時の性質、および設計時に捕捉できないために、本質的に危険であると思います。

これらはランタイム例外を歓迎し、従うだけで複雑なデバッガーとウォッチを必要とします。

クラスをシールするときに使用されるため、継承は不可能です。ただし、オブジェクトを損傷することなくオブジェクトを拡張するためのより良い方法があります。

私の2セント

8

パッチの適用は一般的には最後の手段である必要があり、サルのパッチはさらにそうです。問題は主に保守性の1つです。

昔、私のLinuxカーネルには、ビデオカードドライバと2つの専用アプリケーションに必要な3つの個別のパッチが適用されていました。それらの2つには矛盾する変更があり、それらの違いを解決するには4番目のパッチが必要でした。今度は上流のカーネルでセキュリティの問題が修正されたときはいつでも、これら3つのパッチのベンダーが新しいカーネルバージョンへのアップデートをリリースするのを待つ必要があり、1〜6か月かかりました。他のパッチベンダーが追いつくまでセキュリティパッチ。

数年後、ベンダーはなんとか上流のカーネルソースに含まれるようになり、バランスをとる行為を止めることができましたが、その間に混乱があったことがわかります。必要がない限り、プログラマにそれを与えないでください。

4
Karl Bielefeldt

いいえ、これはソフトウェア開発の標準的な手法ではありません。深刻な問題を解決するための回避策として残っており、明らかな欠点があります。 Liskov Substitution Principle の違反が思い浮かびます。モンキーパッチは、プログラムについて推論することを非常に難しくします。独自のプログラムの場合は、コードをそれが属する場所に配置する必要があります。サードパーティのライブラリの場合、パッチが次のバージョンのライブラリで動作しないという危険に常にさらされています。

もちろん、あなたが何をしているかを知っていて、 [〜#〜] solid [〜#〜] ソリューションを実装する時間がない場合は、モンキーパッチが役立ちます。ただし、これは決してこれを標準的な手法と見なして、モンキーパッチ上にモンキーパッチを構築する必要があります。

ところで、サルのパッチの単体テストを書いたことはありますか?

3
scarfridge