「モンキーパッチ」の背後にある正式なデザインパターンとは何ですか?
-
11-09-2019 - |
質問
重要な CS の質問はこちら:Gamma などにリストされているデザイン パターンのうち、モンキーパッチをカバーするもの (ある場合) はどれですか?さらに、モンキーパッチ適用が適切な問題のクラスと、サブクラス化?コア ライブラリ クラスのバグにパッチを適用することが 1 つですが、他にもありますか?スタックオーバーフローでのモンキーパッチについては、たくさんの騒ぎや騒ぎを耳にします。皆さんのほとんどは、それについて強い不安を抱いているようですが、プログラマーとして、一般的な機能部分をカプセル化して、レール内のオブジェクト モデルに含めることができる機能がとても気に入っています。
たとえば、thoughtbot-paperclip を考えてみましょう。今日存在するモンキーパッチ アプローチではなく、なぜそれをサブクラス化したいと思うのでしょうか?
ありがとう、-eric
解決
モンキーパッチはデザインパターンではないと思います - コアクラス拡張は彼らが無視しているように見える言語機能です。
残りについては、Jeff Atwood の見解をご覧ください。 彼のブログのこの記事.
彼 (そして私の) 意見では、モンキーパッチの最大の問題は、既存のメソッドを変更する場合、デバッグが非常に困難になる可能性があることです。私たち人間は、機械のように「あちこちの小さな断片」をすべて追跡することはできません。サブクラスはより明確な分離を確立します。
したがって、モンキーパッチ適用に関する私の個人的なルールは次のとおりです。
- モンキーパッチを適用しなくても問題なく動作する場合は、モンキーパッチを使用しないでください。
- 新しいメソッドをクラスに追加することはできますが、既存のメソッドを変更することはできません。
- 非常に目に見えて明白な方法でそれを実行してください。非表示の /myvendor/submodule/se.rb ではなく、 /lib にある string_extensions.rb というファイル。
- ローカルである必要があります。ライブラリを使用しないクラスは影響を受けません。
さて、あなたの例に移ります:ペーパークリップ。
- 私の知る限り、ActiveRecordクラスにメソッドを追加しますが、既存のクラスは変更しません
- を追加する必要があります
has_attachment
ペーパークリップを使用するクラスへのディレクティブを追加する必要があります。それ以外の場合は影響を受けません。
したがって、変更は局所的で明白です(実際には、それはなんとかなっていると思います) 改善する デバッグ:私たち人間にとって読みやすい has_attachment
の代わりに class MyModel < Paperclip::ActiveRecordWithAttachment
).
この場合、サブクラス化も悪い考えです。なぜなら、サブクラスを使用する別のプラグインに加えてペーパークリップを使用できないからです。レールは単一継承されています。
Paperclip の場合、それは明らかに has_a
愛着との関係ではなく、 is_a
1つ。それはサブクラス化の適切な使用ではないと主張する人もいるでしょう。
最後に、Paperclip では場合によってはサブクラス化が必要になることを指摘しておきます (ペーパークリップ プロセッサを作成するにはサブクラス化を使用する必要があります)。