Meyer, Bertrand. Object-oriented software construction. Prentice Hall, second edition, April 1997, ISBN 0136291554.
I am pretty conservative about new fads. For a long time I resisted objects, but now I'm a believer. They really do help you subdivide a design in a rational way, and I really am reusing a lot more code now.
Meyer's work is the best single book I've seen on both the why and the how of objects. His examples are in his own language, Eiffel, but I find they translate easily into any good object language (especially my favorite, Python).
Incidentally, I didn't learn o-o design from this book, although I could have. I learned it in an intense three-hour course at New Mexico Tech from the excellent and lamentably departed Dr. Jeff Putnam. At the end of this course, he told us that we had not ``gotten it.'' Then he confessed that he had read several authorities that say you need a year and a half to understand o-o design. He had hoped to get us up to speed in a semester, since that's as long as you get for one course, but failed.
About a year and a half after starting this course, I realized that I had pretty much gotten it, and have been a convert since.
Caveat: There are parts of object-oriented design I still disagree with. I think long chains of inheritance are as hard to manage as lots of global variables (an idea I got from my Tandem colleague Grant Munsey at a startup called Pen Pal Associates). I prefer delegation to inheritance in most cases; see Gamma's Design Patterns for a discussion of delegation.