Often when designing anything it is all to easy to forget the simple fact that when you add 1 to a number you will eventually be doing ADDQ.L #1, D2.
I follow, but not rigidly, the following rules of thumb
If you have a design with 2 classes you probably should be writing something procedural.
If you have a design with more than 30 classes it's probably time to revisit the design.
Now let me explain what I mean buy the ends squeezing the middle. It's actually quite simply really, it's a design rule that I apply to keep the design small and compact. The weight of the design really should be at the extremities, i.e. the structure and the implementation. When I've got a myriad of objects I tend to think that I've missed the primary point and that there is a real abstraction missing
The best example I can think of is the payments side of an e-commerce (or point of sale) application. We (the people) think of paying as being a distinctly different operation to that of buying, when in fact they are two sides of the same coin, and by simply treating a payment as an opposing value purchase it will enable much reuse of code. Failing to realise this will leave the code messy (JT deserves credit for this flash of inspiration and insight).
The main point that I'm trying to make is to distill down to the absolute minimum the number of classes in any given system; remember this:
It is better to find the similarities than to highlight the differences