My question then is: where is the sweet spot? What's the right amount of OOP before it becomes overkill? Is it perhaps a matter of domain, and therefore some domains will benefit much less of OOP?
OOP is great when your main focus are data structures. Many enterprise applications are basically just transforming data from one system to another. Being able to come to an unknown code and figure out what is the format of input and output just by reading couple of classes is a godsend. Even in this case use OOP features sparingly (beware of deep hierarchies, contrived polymorphism etc).
On the other hand when your problem is more about algorithms and evaluation of data you might choose more functional approach.
Hybrid (object+functional) approach is getting even to the enterprise world - SOA suggests to have dumb (possibly immutable) data objects for business objects (just like struct in C) and service objects that perform operations on these data objects (not unlike functional programming). Similar pattern is with dependency injection frameworks that rely heavily on singletons (Spring) - many beans become just containers for stateless functions.
OOP is not silver bullet (nothing is for that matter), but it is a very useful tool.
* The sweet spot is to use OOP only when needed.
* Abstract your core functions to the max
Here is a real life example.
I write a software which is based mostly on functions. A php based CMS
If you look at it from aside, you will say its huge and probably needs a lot of code (and objects).
The truth is that the core set of functions are less than 20 and less than 100K of code.
If you write your functions well, you don't need OOP and you will have
- less code
- less memory usage (functions free memory after run)
- less problems
I think that it's a question of how difficult it is to hold the entire idea in your head. The utility of OOP is in breaking down a difficult idea into manageable parts; if you can commandingly capture the entire thing in a thought, OOP is overkill. Write your program and be done with it; tweak when needed. If you find yourself backtracking and needing to map things out on paper, though, OOP is probably a much better fit.
So my answer is basically, "Can you explain it in the elevator?"