Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monkey-patching Vs. S.O.L.I.D. principles?

Tags:

I'm slowly moving from PHP5 to Python on some personal projects, and I'm currently loving the experience. Before choosing to go down the Python route I looked at Ruby. What I did notice from the ruby community was that monkey-patching was both common and highly-regarded. I also came across a lot of horror stories regarding the trials of debugging ruby s/w because someone included a relatively harmless library to do a little job but which patched some heavily used core object without telling anyone.

I chose Python for (among other reasons) its cleaner syntax and the fact that it could do everything Ruby can. Python is making OO click much better than PHP ever has, and I'm reading more and more on OO principles to enhance this better understanding.

This evening I've been reading about Robert Martin's SOLID principles:

  • Single responsibility principle,
  • Open/closed principle,
  • Liskov substitution principle,
  • Interface segregation principle, and
  • Dependency inversion principle

I'm currently up to O: SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.

My head's in a spin over the conflict between ensuring consistency in OO design and the whole monkey-patching thing. I understand that its possible to do monkey-patching in Python. I also understand that being "pythonic" is to follow common, well-tested, oop best-practices & principles.

What I'd like to know is the community's opinion on the two opposing subjects; how they interoperate, when its best to use one over the other, whether the monkey-patching should be done at all... hopefully you can provide a resolution to the matter for me.

like image 450
Phillip B Oldham Avatar asked Nov 15 '08 23:11

Phillip B Oldham


2 Answers

There's a difference between monkey-patching (overwriting or modifying pre-existing methods) and simple addition of new methods. I think the latter is perfectly fine, and the former should be looked at suspiciously, but I'm still in favour of keeping it.

I've encountered quite a few those problems where a third party extension monkeypatches the core libraries and breaks things, and they really do suck. Unfortunately, they all invariably seem stem from the the third party extension developers taking the path of least resistance, rather than thinking about how to actually build their solutions properly.
This sucks, but it's no more the fault of monkey patching than it's the fault of knife makers that people sometimes cut themselves.

The only times I've ever seen legitimate need for monkey patching is to work around bugs in third party or core libraries. For this alone, it's priceless, and I really would be disappointed if they removed the ability to do it.

Timeline of a bug in a C# program we had:

  1. Read strange bug reports and trace problem to a minor bug in a CLR library.
  2. Invest days coming up with a workaround involving catching exceptions in strange places and lots of hacks which compromises the code a lot
  3. Spend days extricating hacky workaround when Microsoft release a service pack

Timeline of a bug in a rails program we had:

  1. Read strange bug reports and trace problem to a minor bug in a ruby standard library
  2. Spend 15 minutes performing minor monkey-patch to remove bug from ruby library, and place guards around it to trip if it's run on the wrong version of ruby.
  3. Carry on with normal coding.
  4. Simply delete monkeypatch later when next version of ruby is released.

The bugfixing process looks similar, except with monkeypatching, it's a 15 minute solution, and a 5-second 'extraction' whereas without it, pain and suffering ensues.

PS: The following example is "technically" monkeypatching, but is it "morally" monkeypatching? I'm not changing any behaviour - this is more or less just doing AOP in ruby...

class SomeClass   alias original_dostuff dostuff   def dostuff     # extra stuff, eg logging, opening a transaction, etc     original_dostuff   end end 
like image 161
Orion Edwards Avatar answered Sep 19 '22 14:09

Orion Edwards


In my view, monkeypatching is useful to have but something that can be abused. People tend to discover it and feel like it should be used in every situation, where perhaps a mixin or other construct may be more appropriate.

I don't think it's something that you should outlaw, it's just something that the Ruby guys like to use. You can do similar things with Python but the community has taken the stance that things should be simpler and more obvious.

like image 44
Brian Lyttle Avatar answered Sep 16 '22 14:09

Brian Lyttle