September 20, 2004
I recently blogged about how pure object oriented programming is oversold. Well, evidently Paul Graham agrees with me:
Object-oriented programming generates a lot of what looks like work. Back in the days of fanfold, there was a type of programmer who would only put five or ten lines of code on a page, preceded by twenty lines of elaborately formatted comments. Object-oriented programming is like crack for these people: it lets you incorporate all this scaffolding right into your source code. Something that a Lisp hacker might handle by pushing a symbol onto a list becomes a whole file of classes and methods. So it is a good tool if you want to convince yourself, or someone else, that you are doing a lot of work.
I've found that a little object orientation goes a long way
. Pushing too far into "everything must be an object" territory leads to, well, exactly what Paul describes above-- giant masses of repetitive code that someone is going to have to maintain. I like to err on the side of simplicity, and that typically means the approach that produces the least volume of source code.
Posted by Jeff Atwood
"Well, Bob, this code works, but doesn't it violate the Liskov Substitution Principle?"
Heh. Good stuff.
Full blown "pure" OO design is also dangerous on mid-size projects as well. In fact, I'd argue only a tiny subset of all development (eg, .NET language itself) really qualifies as large enough to benefit. As I said in my post-- a little OO goes a long way!
What's particularly painful is that OO ends up being a wolf in sheep's clothing; it's supposed to make our coding easier, not create more code and more complexity in the name of purity. Whatever that is.
Eric Lippert once made this comment ( http://blogs.msdn.com/ericlippert/archive/2004/03/18/92422.aspx ):
"What I sometimes see when I interview people and review code is symptoms of a disease I call Object Happiness. Object Happy people feel the need to apply principles of OO design to small, trivial, throwaway projects. They invest lots of unnecessary time making pure virtual abstract base classes -- writing programs where IFoos talk to IBars but there is only one implementation of each interface! I suspect that early exposure to OO design principles divorced from any practical context that motivates those principles leads to object happiness. People come away as OO True Believers rather than OO pragmatists."
This is why you should use refactoring to objects. Write it simple... Then refactor out what you want to and leave the rest simple.
It's funny, when I read the Refactoring book, I realized that this is something I had intuitively done for years-- habitually going back to old code to rework it and simplify it based on all the new things I understood at that (later) point in the project.
It's still a good book, but if you aren't already refactoring all the time prior to reading this book.. uh, maybe time for a new career :)
Personally, I don't know how writing things OO and over commenting your code have ANYTHING to do with each other. Your comments baffle me. If you're writing OO and you find you are writing a lot of repetitive code then allow me to enlighten you: you are coding it improperly. The entire idea of OO is to push common functionality down to super classes, thereby eliminating repetitive code.
And I also argue that OO adds complexity to programming. Consuming OO objects should be easy as pie. Writing them may be a little more complex, but the pay off is when it comes time to use them.
I know a lot of people that do this. They tend to overbuild a complicated hierarchy of objects, because conceptually that seems like the natural way to model the data; but in reality, none of the objects are ever subclassed after they are created, leading to a confusing morass of method calls and an overly brittle interface.
I long for terseness.
Jeff Atwood posted this article on Coding Horror, which details his (and others') views on object oriented programming. A very interesting debate, since most of us were taught that OO is the king of kings...
Correction: "or exaggerate the frequency change-scenarios..."
Should be: "or exaggerate the frequency of change-scenarios..."
(In other words, they tend to remember the kinds of changes that OO seems to favor and forget more realistic change patterns. I think this is similar to TV ads that make you over-focus on split-ends, out-of-style foods, etc. by pointing them out over and over. OO is one of the greatest snowjobs of software engineering since the AI hype of the 80's.)
Re: "What OOP brings to the table is an easy vehicle for Separation of Concerns."
This is nearly impossiple for most real business software because concerns naturally interweave. We need ways to manage inter-connections between concepts, not pretend like they don't exist. One of the best ways to do this is put the model into an RDBMS such that concerns can be presented in various perspectives as needed via queries with different joins. OO tends to hard-wire one concern at the expense of all others. OO'ers don't think "meta" enough, trying to model everything with static trees or hard-wired tangled navigational OO-pointer messes.
Re: "Could this be done with plain old Structured Programming? Sure, but not with less code or more maintainable, at least not without simulating OOP to some extent."
Prove it by showing us real code and how many lines/modules/blocks are changed per change scenario. I've asked for this in the past, and the OO'ers that bother to respond usually offer lame procedural to beat up on, or exaggerate the frequency change-scenarios as found in pro-OO books. Whether they crippled the procedural app on purpose or are bad proceduralists, I cannot tell. No wonder they like OO: they s*ck at procedural/relational. PROVE IT WITH CODE, NOT brOOchures!
Your day job wouldn't be DBA by any chance would it?
I've always thought of OOP the same way I view "functional" programming but things mainly have different names and basically can break down to the same organization (filenames vs wrappers vs OOP objects vs other types of objects or libraries).
I prefer C over C++ but things like PHP seem to be much easier on the eyes if using OOP (probably the HTML/Templating factor). I definitely think OOP is overhyped and we would be completely fine without it.
I'm an advocate for "Pure" object-oriented design, so I'll drop in my two cents, less the flame. I think with most programming, there is no "one" right way to do anything. OOP adds more complexity to programming, and hence more ways to do something. In reality, OOP is virtually useless without modeling. You'll easily double your development time with no (or improper) modeling.
The more people try to create Object-Oriented Code without a blueprint (i.e. UML, RUP, ICONIX), the more cumbersome the application will be. You'll be constantly re-writing, re-wiring, and re-thinking your application as you go along trying to keep it "Perfect".
This also goes along the lines of the "Educated Developer" versus the "Kamikazee Developer". The educated developer tries to learn about his technology before jumping in. The Kamikazee developer jumps right in. There's nothing right or wrong with either, except in the world of OOP. With more features comes more rules: rules that must be learned. If you don't follow the rules, don't bother.
A good example is the "Object State" rule, which is sadly the one I see broken the most. For example, so many times I've seen something like object.delete(intObjectID) or object.ID = intObjectID (hungarian notation used for illustration only). The former should delete the object based on it's state, which should contain an ID property. The latter should never be allowed. Any property that changes the identity of the object should be read-only or protected, and set only on construction. If you need a different object, construct another one. If you want to reuse your object, use component services (Like COM+).
In short, I think purest OOP is a good thing, when implemented correctly. It all goes back to the cardinal rule of programming: Just because you can, doesn't mean you should.
What book is that? I'd like to read it.
I find you can also refactor too much (If I'm using the term correctly). I find myself revisiting code all-too-often, fixing it to work the "Right Way" after learning some important lessons (Like using a Dictionary instead of a HashTable, or finding that some functionality belongs in a super-class, and not in the abstract).
What OOP brings to the table is an easy vehicle for Separation of Concerns. That means I can treat different things as the same because I don't care about how they're different, only about how they're the same in my current context. For example, I can treat my house and my car and my job as the same because they all have impact on my personal budget. By using the tools of OOP, I can create a framework for this, and easily add other 'things' to my budget later.
Could this be done with plain old Structured Programming? Sure, but not with less code or more maintainable, at least not without simulating OOP to some extent.
"writing programs where IFoos talk to IBars but there is only one implementation of each interface!" Sorry but I can't help to sign up and post against this.
(At least in .net) you can't mock if you don't use interface. End of story. And if you can't mock, you can't unit test. Yes yes, there are hax/super mocks (that can even intercept/mock extension methods) etc etc.
But why make life difficult?
Create interface -> Mock -> test -> rinse repeat -> ???? profit?
As JA said "A little OO goes a long way". Amen.