monkeypatchingは優れたプログラミング手法と見なされていますか?


15

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

ただし、主流プロジェクト、たとえばGeventのgevent.monkeyモジュールでこの手法が「通常の方法」として使用されているのを見てきました。

モンキーパッチは、主流であり、通常の、受け入れ可能なプログラミングプラクティスになりましたか?

参照:ジェフ・アトウッドによる「人間のためのモンキーパッチング」


13
私は、モンキーパッチという名前の何かは、優れたプログラミング手法とは見なされていないと思います。それが何であるかさえ知らずに、その名前だけで。
-littleadv

サードパーティが必要な修正を行いたくない場合はどうなりますか?

1
@Thorbjørn:良い質問です。一方で、モンキーパッチングは好きではありません。一方で、プロジェクトのクローンを作成し、ローカルパッチをマイナーな問題に留めるという考えはあまり好きではありません。
バルテック

1
@littleadv:...「hot fix」/「on-the-fly fix」または「runtime fix」と呼んでもいいですね。;) それはすべて同じです。
-dagnelies

3
javascriptはコンセプトを中心に構築されています
-ZJR

回答:


19

いいえ。ただし、時々、モンキーパッチは(コードが壊れているよりも)悪の度合いが低いです:)。ルビーの猿パッチの私の一般的なルールは次のとおりです。

  • monkey-patchには本当に正当な理由があります(一時的な重要な修正プログラムが正当な理由です。ActiveSupportで作業している場合を除き、to_sメソッドの素晴らしいフォーマットはそうではありません)

  • それらを可能な限り透明にします:コードベースの特定の場所に配置し、ファイルを分離し、monkeypatchの理由を説明するドキュメントを作成します(例を示します)。

  • 簡単に削除できます-ドキュメントには、削除に関する情報と監視対象を含める必要があります。多くのサルパッチは一時的なものなので、簡単に削除できるはずです。


11

はい、monkeypatchingは非常に便利です!

どういうわけか、名前は人々の認識に大きな影響を与えるようです。それを「monkeypatch」と呼ぶと音が悪く、「hot fix」または「on-the-fly fix」と呼ぶといいですね。

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

例えば:

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

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

さて、そのようにパッチを提供するという質問のために...まあ...なぜだ。大きなリリースではなく小さなパッチをダウンロードするだけです。まあ、あなたはそれを止めることなくサーバーにパッチを当てることさえできる、素晴らしい!そして、ある日、より大きなアップデートのために最新のリリースを取得することもできます。けっこうだ。そう、私は良いこととして「ランタイムパッチ」に投票します。

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

もちろん、最終的には、他のすべてと同様に、それをどのように使用するかという問題です。あなたは素晴らしいオブジェクト指向のものとくだらないものを作ることができます、それはすべて同じです。

編集:

独自のライブラリにパッチを適用する場合でも、サードパーティのライブラリにパッチを適用する場合でも、いくつかのケースの区別を追加します

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

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


1
誰もそれが役に立たないとは言いません。ただし、一般的には良い習慣ではありません。そして、「ホットフィックス」と「その場での修正」は私には良く聞こえません。
ルーカスStejskal

1
さて、アプリケーションの動作をオンザフライで変更する機能は非常に便利で、大きなものであればさらに便利です。ちなみに、バックアップとして古いメソッドを保存するコードと、必要に応じて自動的にロールバックするコマンドを使用することもできます。可能性は途方もないです!
-dagnelies

これは強力で便利な機能であることに同意します。ただし、非常に危険(特にRubyの場合)であるため、細心の注意を払って使用する必要があります(特に標準およびサードパーティのライブラリの変更)。サルパッチを適用したいくつかのサードパーティライブラリに依存するアプリケーションを保守しようとしたことがありますか?何らかのライブラリを更新しようとするたびの災害のレシピ。
ルーカスStejskal

1
ええ、私は、これらのパッチを不注意に、意図しない方法で使用したり、乱用したりすると、すぐに乱雑になる可能性があることに同意します。どんなコンセプトでも悪用したり、何かを台無しにしたりできるように。しかし、そうでなければ、それらがきちんと整理され、透明であり、それらがすべて次の大きなリリースで流れるなら、それは私にはきれいに見えます。...しかし、私は非常にパッチが適用されたRubyライブラリの経験がありません。
-dagnelies

...後者のケースに関するコメントを追加しました。
-dagnelies

8

すべてのパッチは、実行時の性質と設計時に捕捉できないため、本質的にリスクが高いと考えています。

ランタイム例外を歓迎し、従うために複雑なデバッガーとウォッチを必要とします。

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

私の2セント


4

一般にパッチを当てるのは最後の手段であり、猿のパッチはさらに当てはまります。この問題は、主に保守性の1つです。

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

数年後、ベンダーはアップストリームカーネルソースに含まれるようになり、バランス調整を停止することができましたが、その間に混乱が生じたことがわかります。必要がない限り、プログラマにそれを与えないでください。


3

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

もちろん、モンキーパッチは、自分が何をしているかを知っていて、SOLIDソリューションを実装する時間がない場合に役立ちます。しかし、あなたがすべき決してこのモンキーパッチ時に標準技術とビルドモンキーパッチを検討していません。

ところで、モンキーパッチの単体テストを書いたことがありますか?


ここでLSPを適用できるとは思わない。サブタイプに関する非常に具体的な定義があります。
コンラッドルドルフ

@KonradRudolph Monkeyがオブジェクトにパッチを適用すると、そのタイプが変更されます。動的に型付けされた言語では、タイプuと同じインターフェースを持つすべてのタイプtは、uのサブタイプです。それがアヒルのように歩く場合
...-スカーフリッジ

「…そのタイプを変える」–十分に公平。理にかなっています。
コンラッドルドルフ

RE「ソフトウェア開発の標準的な手法ではありません。」、テストのためにPythonで*常時および主要なライブラリで行われているようです
トミー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.