I quickly become nervous and neurotic when I become uncertain about “what will this code do?” and especially if I fear that it might do something different six months from now due to reasons that are beyond my control.
My general approach to dealing with the problem is to build a set of application-specific “helper” objects, which spell out exactly what functionality my application does actually require, and which by some means “reflect” the requests that are made to them to whatever bit of code is (presently...) tasked with carrying it out.
“Subclassing” and other fancy-pants ;-) methodologies (although of course I do routinely use them) make me nervous because they construct a system of mutual dependency that is just waiting on “the one exception to the rule” that will bring the Bill Ding™ (yes, the toys have a website...) come a’tumbling down. “We just acquired who?” “Marketing wants to do what?!?!” :-O Elegant software constructions can save a lot of time when they are written, but they are also mutually dependent upon one another, and those dependencies have a nasty way of becoming nasty. I do not offer a generalized solution to the issue because I don’t think that one exists. But “monkey patching” is specifically frightening to me because, even if it “solves” the problem now, I have no confidence that it will continue to solve the same problem forever. I avoid the practice, and those similar to it, for these reasons. You can only rely on Monster.Com to bail you out so many times before the word starts to get around.