25

私はいくつかの個人的なプロジェクトで PHP5 から Python にゆっくりと移行しており、現在その経験が気に入っています。Python ルートをたどることを選択する前に、私は Ruby に目を向けました。Ruby コミュニティから私が気付いたのは、モンキー パッチが一般的であり、高く評価されていることです。ruby s/w のデバッグの試行に関する多くの恐ろしい話にも出くわしました。なぜなら、だれかが小さな仕事をするために比較的無害なライブラリを含めたのに、誰にも言わずに、頻繁に使用されるコア オブジェクトにパッチを当てたからです。

私が Python を選んだのは、(他の理由の中でも) 簡潔な構文と、Ruby ができるすべてのことを実行できるという事実のためです。Python は OO クリックを PHP よりもはるかに優れたものにしており、この理解を深めるために OO の原則についてますます読んでいます。

今晩、私はRobert Martin の SOLID の原則について読んでいます。

  • 単一責任原則、
  • オープン/クローズド原則、
  • リスコフ置換原理、
  • インターフェイス分離の原則、および
  • 依存性逆転の原則

私は現在、O :ソフトウェアエンティティ (クラス、モジュール、機能など) は、拡張のためにオープンにする必要がありますが、変更のためにクローズする必要があります。

OO 設計の一貫性を確保することと、モンキー パッチ全体との間の対立について頭が混乱しています。Pythonでモンキーパッチを適用できることを理解しています。また、「pythonic」であることは、よくテストされた一般的な oop のベスト プラクティスと原則に従うことであることも理解しています。

私が知りたいのは、相反する 2 つのテーマに関するコミュニティの意見です。それらがどのように相互運用されるか、一方を他方よりも使用するのが最善の場合、モンキーパッチを行う必要があるかどうか...うまくいけば、問題の解決策を提供していただけます。

4

8 に答える 8

29

モンキー パッチ (既存のメソッドの上書きまたは変更) と新しいメソッドの単純な追加には違いがあります。後者はまったく問題ないと思いますし、前者は疑わしいと見なされるべきですが、それでも私はそれを維持することに賛成です.

私は、サードパーティの拡張機能がコア ライブラリにモンキー パッチを適用して物事を壊すという問題にかなり遭遇しましたが、それらは本当にひどいものです。残念ながら、それらはすべて、サード パーティの拡張機能の開発者が、実際にソリューションを適切に構築する方法を考えるのではなく、最も抵抗の少ない道を選んだことに起因しているように見えます。
これはひどいですが、人々が時々自分自身を切るのはナイフメーカーのせいであるのと同じように、モンキーパッチのせいではありません.

モンキー パッチの正当な必要性をこれまでに見たのは、サード パーティまたはコア ライブラリのバグを回避する場合だけです。これだけでもプライスレスですし、それができなくなったら本当にがっかりです。

私たちが持っていた C# プログラムのバグのタイムライン:

  1. 奇妙なバグ レポートを読み、問題を CLR ライブラリのマイナーなバグまで追跡します。
  2. 奇妙な場所で例外をキャッチし、コードを大幅に侵害する多くのハックを含む回避策を考え出すのに何日も費やします
  3. Microsoft がサービス パックをリリースしたときにハッキングされた回避策を見つけるのに何日も費やす

私たちが持っていたレールプログラムのバグのタイムライン:

  1. 奇妙なバグ レポートを読み、問題を ruby​​ 標準ライブラリのマイナーなバグまで追跡する
  2. 15 分間マイナー モンキー パッチを実行して、Ruby ライブラリからバグを削除し、Ruby の間違ったバージョンで実行された場合にトリップするようにガードを配置します。
  3. 通常のコーディングを続行します。
  4. Ruby の次のバージョンがリリースされたら、monkeypatch を削除するだけです。

バグ修正プロセスは似ていますが、モンキーパッチの場合は 15 分の解決策であり、5 秒の「抽出」ですが、それがなければ痛みと苦しみが続きます。

PS: 次の例は「技術的に」モンキーパッチを適用していますが、「道徳的に」モンキーパッチを適用していますか? 私は動作を変更していません-これは多かれ少なかれRubyでAOPを行っているだけです...

class SomeClass
  alias original_dostuff dostuff
  def dostuff
    # extra stuff, eg logging, opening a transaction, etc
    original_dostuff
  end
end
于 2008-11-17T20:23:48.977 に答える
5

私の見解では、モンキーパッチはあると便利ですが、悪用される可能性があります。人々はそれを発見し、あらゆる状況で使用する必要があると感じる傾向があり、おそらく mixin やその他の構造がより適切である可能性があります。

禁止すべきものではないと思います。Ruby 関係者が好んで使用するものです。Python でも同様のことを行うことができますが、コミュニティは、物事はより単純で明白であるべきだという立場をとっています。

于 2008-11-15T23:47:37.617 に答える
4

モンキーのパッチ適用はルビー明示的ではなく、javascript 全体で行われ、負の (IMO) 効果があります。

私の個人的な意見は、サルのパッチ適用は、

a) 必要な言語の新しいバージョンで利用可能な古いバージョンの言語に機能を追加します。

b) 他に「論理的な」場所がない場合。

ADDITIONなどの基本機能の動作方法を変更する機能など、モンキー パッチを本当にひどいものにする簡単な方法がたくさんあります。

私のスタンスは、避けることができるならそうするということです。

うまく回避できたら、よろしくお願いします。

どうしても避けられない場合は、200 人の意見を聞いてください。

私の嫌いなところは、関数オブジェクトを拡張する mootoolsです。はい、できます。JavaScript がどのように機能するかを学ぶだけでなく、

setTimeout(function(){ 
    foo(args); 
}, 5000 ); 

関数が独自の関数を持つように、すべての関数オブジェクトに新しいメソッドが追加されました (はい、冗談ではありません)。

foo.delay( 5000 , args );

この種のがらくたが有効であるという追加の効果がありました:

foo.delay.delay( 500,  [ 500, args ] ); 

そして、そのように無限に。

結果?あなたはもはや図書館と言語を持っていません。あなたの言語は図書館に屈服します。図書館がたまたま範囲内にある場合、あなたはもはや言語を持っていません。代わりに、コマンドの新しいサブセットを学習して、完全に失敗しないようにする必要があります (過度の速度低下を犠牲にして!)

foo.delay も独自のメソッドを持つオブジェクトを返したことに注意してください。

x = foo.delay( 500, args ); 
x.clear(); 

そしてさえ

 x.clear.delay(10); 

これは非常に便利に聞こえるかもしれませんが、これを実行可能にするために使用される膨大なオーバーヘッドを考慮する必要があります。

 clearTimeout(x); 

とても厳しい!

(免責事項:mooを使用してからしばらく経ち、忘れようとしましたが、関数名/構造が間違っている可能性があります。これはAPIリファレンスではありません。詳細については、サイトを確認してください(申し訳ありませんが、APIリファレンスはひどいです!) )

于 2008-11-15T23:55:05.417 に答える
4

Mokeypatching は一般的に間違っています。適切なサブクラスを作成し、メソッドを追加します。

プロダクションコードでモンキーパッチを一度使用しました。

問題は、REST が GET、POST、PUT、および DELETE を使用することです。しかし、Django テスト クライアントは GET と POST しか提供していません。PUT (POST など) と DELETE (GET など) のメソッドにモンキーパッチを適用しました。

Django クライアントと Django テスト ドライバーの間の結合が緊密であるため、完全な REST テストをサポートするためにモンキー パッチを適用するのが最も簡単であると思われました。

于 2008-11-16T01:47:53.880 に答える
3

Ruby のオープン クラスと Open-Closed Principleに関するこの議論は、啓発的なものになるかもしれません。

私は Ruby が好きですが、モンキーパッチは物事を成し遂げるための最後の手段だと感じています。すべてが同じであれば、関数型プログラミングの良さを少し加えた従来のオブジェクト指向手法を使用することを好みます。

于 2008-11-16T01:07:37.533 に答える
2

私の目には、モンキー パッチは AOP の 1 つの形式です。Aspect-Oriented Design Principles: Lessons from Object-Oriented Design (PDF)の記事では、SOLID およびその他の OOP 原則を AOP に適用する方法についていくつかのアイデアを提供しています。

于 2009-03-11T00:02:38.690 に答える
1

クラスのクライアントは、そのクラスが一貫して機能することを期待できるはずなので、モンキーパッチはOCPに違反しているのではないかと最初に考えました。

于 2008-11-16T00:20:02.620 に答える
0

モンキーパッチは単純に間違っています、私見です。あなたが以前に言及したオープン/クローズの原則に出くわしたことはありませんが、それは私が長い間保持してきた原則であり、100%同意します. 私は、モンキーパッチをより大きなスケールでのコードの匂い、いわばコーディング哲学の匂いと考えています。

于 2008-11-16T00:00:31.477 に答える