KarlKnechtel here, ranting about ObjectOriented "purists":
I like being in the presence of OoDesigners and OoExpert?s. But what I cannot stand are the OoPurist?s (some would call them ObjectWeenies) who take very strict definitions of what ObjectOrientedProgramming is and what it requires (see DefinitionsForOo).
In particular, I take offense to statements of the form "As soon as you as a programmer (do X in your code, or use language Y), you are no longer writing ObjectOriented code, but some (description of combination of OO and procedural/etc. code which makes it sound like some Frankenstein creation)." The tone comes off as very aggressive to me and I don't need to hear that. Plus, some values of X rather disturb me. I've heard people go so far as to say that in Java, the design of the System class is a horrible mistake, and you simply can't have "object oriented" code if you make calls to System.[in|out|err].* anywhere. And go further to say that you should at least mitigate the problem by doing it OnceAndOnlyOnce, by making some Singleton object which acts as a wrapper by delegating calls to System... Give me a break. What's next? Barring use of primitives outright in favor of the wrapper objects, because it's a "mistake" in Java that primitives aren't first-class objects anyway? JavaObjectOverheadIsRidiculous.
The effect on the outside code is to change "System.out.println(...)" to "MySystemWrapper.outPrintln(...)" or something along those lines. Maybe "MySystemWrapper.out().println(...)", but then you're violating the LawOfDemeter it seems. Since there are a fair number of methods, maybe you even implement the Command pattern and do "MySystemWrapper.delegateOut(Println.getInstance(), ...)". Again, Give me a break. Sure, now you can pass around references to MySystemWrapper. YouArentGonnaNeedIt.
But yes. Just one example there. Wow, really good at ranting aren't I?
Similar issues regarding "system.print()" examples are in ResponsibilityDrivenDesignConflictsWithYagni.
I believe reasonableness comes with experience. I like the OO model a lot, but I also recognize cases where it fails and forcing the code into a pure OO form does not provide benefit out-weighing the cost. Two examples.
1) Inheritance fails when the system logically demands a widely used singleton instantiation of a class. Examples are typically a logging class or a database connection. The OO solution is usually to pass the singleton in via a constructor or initialize function, but this can be cumbersome when you start subdividing classes. A non-OO alternative is a global class.
2) Encapsulation fails when the system is comprised of multiple subsystems. For example, we have a COBOL subsystem that preprocesses data and passes it over to a VB and C++ subsystem on a different platform. To encapsulate this data, we would need a single class containing both the COBOL functions and the VB and C++ functions. The pragmatic approach is to "un-encapsulate" and just pass the raw data between subsystems. A similar problem is usually encountered with GUI code, where raw data is passed from GUI classes to business classes. I have never seen anyone attempt to write a class with GUI functions, business rule functions, and database access functions within a single class to provide "pure" data encapsulation.
The OO model is a good one, but it does not make sense to become a coding martyr to be 100% pure. When the OO model falls down, use something else.
Uh, oh.
See also: WhenToUseWhatParadigm, ArgumentsAgainstOop