Below I will talk about Object-Oriented programming mistakes and misconceptions I have encountered, both in talking to candidates and working on code written by others. It should not be construed as an attack on non-OO programming paradigms, only on OO applied incorrectly.
When I interview candidates that put OO on their resume, they can usually describe basic concepts like encapsulation and inheritance, maybe even abstraction and polymorphism. When I ask for specifics, the better candidates can give one or two examples, but they usually trot out basic textbook scenarios, often the same one involving widgets, shapes, squares and circles. When I ask how they have used the OO principles in their own work, the response is typically a depressing silence.
That suggests to me that few developers claiming to use OO employ these tools in their designs. This is confirmed by most codebases I have worked on. Especially codebases with long histories involving different developers.
One frequent symptom of this is arbitrary class divisions, so that you see a base and a derived class for no appearent reason. For instance, a CHTTPHeaders class with a CHTTPHeadersBase subclass, with no rhyme or reason to which class owns a particular method. Now, this division might make sense if CHTTPHeadersBase is used in isolation, or is used to derive other classes, but when only the specialized class is used anywhere else in the codebase, and the division of labor between the two classes does not follow any recognizable design principle, then I am tempted to conclude the developer created the hierarchical structure arbitrarily.
Another symptom is the confusion of the has-a relationship with the is-a relationship. For instance (to stick with the theme), it makes sense that a CHTTPRequest has a CHTTPHeaders. It makes no sense that a CHTTPRequest *is* a CHTTPHeaders. Yet, I often see examples of the latter type of relationship. These examples make me suspect that developers learn about inheritance, are too excited about it and go forth to make prodigious use of the technique, whether it makes any sense or not.
One last example is perhaps the worst: the circular relationship. This situation really throws kinks into my workday. Say you have CHTTPRequest, CHTTPResponse and CHTTPHeaders as separate classes in separate source files, but where each class is dependent upon and has full visibility into the other two. You recognize this easily by noticing that the source file, or worse, the header file, for each includes the header file for both the others. Sometimes developers will overuse the friend modifier to break encapsulation, for a relationship so tight you effectively have a monolithic beast on your hands.
I believe these problems are due to developers really only picking up one of the O’s when they learn Object-Oriented programming. They learn about objects and the techniques for writing classes and encapsulation and inheritance and all that cool stuff. They just never learned to *orient* their design around the objects.
I also believe Object Oriented design, when applied correctly, is one of the more scalable design methodologies for large software projects. I have worked on some large, complex projects that was easy to extend and maintain and a pleasure to work with.