I'm not a fan of object orientation for the sake of object orientation. Often the proper OO way of doing things ends up being a productivity tax. Sure, objects are the backbone of any modern programming language, but sometimes I can't help feeling that slavish adherence to objects is making my life a lot more difficult. I've always found inheritance hierarchies to be brittle and unstable, and then there's the massive object-relational divide to contend with. OO seems to bring at least as many problems to the table as it solves.
Perhaps Paul Graham summarized it best:
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.
Eric Lippert observed a similar occupational hazard among developers. It's something he calls object happiness.
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.
I've seen so many problems caused by excessive, slavish adherence to OOP in production applications. Not that object oriented programming is inherently bad, mind you, but a little OOP goes a very long way. Adding objects to your code is like adding salt to a dish: use a little, and it's a savory seasoning; add too much and it utterly ruins the meal. Sometimes it's better to err on the side of simplicity, and I tend to favor the approach that results in less code, not more.
Given my ambivalence about all things OO, I was amused when Jon Galloway forwarded me a link to Patrick Smacchia's web page. Patrick is a French software developer. Evidently the acronym for object oriented programming is spelled a little differently in French than it is in English: POO.
That's exactly what I've imagined when I had to work on code that abused objects.
But POO code can have another, more constructive, meaning. This blog author argues that OOP pales in importance to POO. Programming fOr Others, that is.
The problem is that programmers are taught all about how to write OO code, and how doing so will improve the maintainability of their code. And by "taught", I don't just mean "taken a class or two". I mean: have pounded into head in school, spend years as a professional being mentored by senior OO "architects" and only then finally kind of understand how to use properly, some of the time. Most engineers wouldn't consider using a non-OO language, even if it had amazing features. The hype is that major.So what, then, about all that code programmers write before their 10 years OO apprenticeship is complete? Is it just doomed to suck? Of course not, as long as they apply other techniques than OO. These techniques are out there but aren't as widely discussed.
The improvement [I propose] has little to do with any specific programming technique. It's more a matter of empathy; in this case, empathy for the programmer who might have to use your code. The author of this code actually thought through what kinds of mistakes another programmer might make, and strove to make the computer tell the programmer what they did wrong.
In my experience the best code, like the best user interfaces, seems to magically anticipate what you want or need to do next. Yet it's discussed infrequently relative to OO. Maybe what's missing is a buzzword. So let's make one up, Programming fOr Others, or POO for short.
The principles of object oriented programming are far more important than mindlessly, robotically instantiating objects everywhere:
Stop worrying so much about the objects. Concentrate on satisfying the principles of object orientation rather than object-izing everything. And most of all, consider the poor sap who will have to read and support this code after you're done with it. That's why POO trumps OOP: programming as if people mattered will always be a more effective strategy than satisfying the architecture astronauts.
One of the most infuriating comments I get from people reviewing code for the CSK or SubSonic is "this [one obscure part of your program] isn't OO mmmm-kay". It seems anything else needs to ride in the back of the architectural bus.
All arguments aside - the ability to creatively think and solve without religious boundaries is what makes developing fun. The OO police are probably gonna pile on here Jeff but well done in speaking up and telling us "Neo" - phytes to "Free our mind".
Good onya!
Rob Conery on March 4, 2007 10:06 AMi like old VB but the new OOP VB.net piss me off. if i want OOP, i go with C#. i use VB for the spaghetti code and damn it that's how i like it. seriously, i love VB because i don't have to code it the OOP way but how do you reuse your code if you don't use OOP?
Jack on March 4, 2007 10:13 AMThis is one reason I'm such a big fan of Test Driven Development (TDD), because it forces you to be that other programmer for a moment.
Why stop at considering the poor sap who has to maintain your code and use your APIs? Why not become that person for a brief moment.
Phil Haack on March 4, 2007 10:44 AMI agree, the main goal in practice is to get your project done. You just have to keep in mind that the project might include more than the first release, so you want to plan for that growth. But in the end, OO isn't the only way to satisfy principles of DRY (for maintainability), modularization and consistency (for concurrent development).
OOP was supposed to make a tree of reusable components deriving from base classes (okay, let's say which in turn derive from Object to make it a tree). But almost every waste of time in OOP happens because people rewrite things from scratch. Most fields of programming would benefit greatly if people just got together and used one framework (for 3D games, say), instead of hodgepodges.
Just imagine how much useless information programmers have to learn just so they can use many programming languages, many frameworks, etc. In C, you close statements with ; and use {} for blocks. In VB statements end with line breaks unless you put underscores at the end, and blocks are written differently. A person making a website has to use PHP, HTML, Javascript and CSS effectively. Frameworks were supposed to get rid of all that.
Of course, as I take on another programming project and notice 100 different frameworks to do the same thing, I have a secret plan. To start my own OS, write everything from scratch, and just have ONE version of everything, so people wouldn't reinvent the wheel 1000 times and try to be better than the others in 2 or 3 aspects.
Yes I know, I'm sure this plan shares some things with very evil plans that other people had. But I really know that dragging and dropping a chatroom onto my page and configuring its properties is much easier than every time slavishly writing javascript. That's visual OO. :)
GregMagarshak on March 5, 2007 1:03 AMMy first major OOP application has only three interfaces and two design patterns - Factory and Template Method. So, instead of worrying that it is TOO simple, I should be happy that it WAS simple?
Gene on March 5, 2007 1:12 AMI totally agree with your point, as I see OO being useful for larger and long term projects. My own hatred of OO overkill is when the objects are so badly designed they can't possibly be extended.
I'd disagree with the viewpoint of VB being for Spaghetti code. Even going back to VB5 "objects" were introduced, and generally did make life easier. It wasn't proper OO but it was a good start.
Paul Tew on March 5, 2007 1:28 AMMy first major OOP application has only three interfaces and two design patterns [..] I should be happy that it WAS simple?
Gene, some might ask what defects in the language cause those two design patterns to be necessary:
http://blog.plover.com/prog/design-patterns.html
But in general, yes!
Jeff Atwood on March 5, 2007 1:36 AMWell, there's objects and then there's Objects. I work in Smalltalk - real objects everywhere and it feels pretty natural.
OTOH, Java's Objects(TM) are characterized by cargo cult engineering. Lots of form of without function of. Factory is just one pattern that is horrifically overused in that world and usually for no good reason.
You have to know when to use sense. Very rare in software. Sometimes a script is just a script.
Todd Blanchard on March 5, 2007 1:40 AMMaking something ridiculously complex for the sake of making it simple is like trying to put out a fire with gasoline.
Some programmers just need to take a deep breath and write code that is a delicious salami sandwich, and not an extravagantly prepared four course meal that tastes like shit.
Opeth on March 5, 2007 1:43 AM“It has been said that democracy is the worst form of government except all the others that have been tried.” - Churchill
Erm, I guess people do go object-crazy. The problem, as I'm sure is documented elsewhere, is the crappy teaching phase driving home that "OO is about all about inheritance" when it's not. Inheritance is a powerful tool that is sorely abused. Most of my object hierarchies are flat, I mark all classes as sealed unless I do intend for someone to derive off of them, and I don't create interfaces until I really need them (and usually it's only for testing so I can swap in a test implementation).
OO to me just provides a better way to hide implementation and abstract ideas away so I can create more complex, but logically simpler programs because I don't have to hold onto all the nuances of everything at once. It's no panacea, but it is nicer to work with when done right.
Anyways, don't throw the baby out with the bathwater. Just because some cars suck, do you stop driving altogether? So, until something better comes along ..
Ed on March 5, 2007 1:51 AMI second Mr. Haack's thoughts. I was very fortunate in both high school and college in having teachers who taught both the thinking structure for OOP and why it works. We consistently had to work in groups and be able to read each others' code at a glance and understand what it did, how, and why.
I didn't understand just how important that was until many years later. It has shaped every program I've touched since.
Phil Deneka on March 5, 2007 1:52 AMJust to second Phil Deneka's point, it took me a few years of programming VB before the point of OO really sank in. I learnt Eiffel before I even touched VB, but without any real world experience of learning from my mistakes.
Paul Tew on March 5, 2007 2:06 AMI semi-agree with your comment about design patterns. Some are just silly, like the Factory pattern, and truly are about working around an issue in the language (for example, the lack of classes as first class object in C++, where you could pass a reference to the Class object instead of a function pointer to the factory). Still, it helps establish a bit of language (saying "a subroutine" instead of "you know, put some code here that we can jump to from a bunch of places, putting the return address over here"), and I'd disagree with Mark in that it eventually leads to the languages supporting the concepts, because it gels into peoples mind as the very same thing, as opposed to people getting stuck to the tiny little difference that don't matter (one guy puts the return address in a register, the other in a global variable, etc). It helps see the big picture.
After a while of "functors" being used in C++, I'm hoping that people will see that they'd really like simple anonymous closures (I'm thinking Perl-style closures, for example), as a first-class construct you can just whip up in the parameters of a function call, say. And it might be possible eventually because we can tell people "what if we made functors even easier and nicer to use?" and they'll know that functors are, see all those they use, and the prospect of getting a better one could catch on.
Other patterns are really more abstract, like the Facade. I mean, "making a function that calls a bunch of functions for you" is kind of a weird feature one would want to have in a language, and one could argue that, well, we already have it!
But I'll have to agree that patterns been really abused. What I particularly despise is some people who seem to insist there can only be one particular way to implement a pattern, when someone looks at my code and asks why I didn't use the Foo pattern, and well, uh, I *did*, but I just did it different than you. That's why there's no concrete "Foo function", it's a *pattern*!
As for the main article, here's a true life example: a co-worker once made a "Convert" class, that didn't have any non-static member, just a few conversion methods. To top it off, he instantiated with "new" rather than just on the stack (this is in C++) and bloody LEAKED IT. Wow.
There's also the opposite trend: the coders who just won't use the language they're using. The most common is the C coders who keep using char* and such in C++, complete with fixed sized buffers, overflows and other fun bits (or when using higher-level languages, can't wrap their heads around a closure). That said, they tend to have to type a lot more to do as much damage as the overzealous OO programmer, so I tend to prefer the C coder (and I can fix their code with small local patches instead of ripping apart some grandiose framework).
Pierre Phaneuf on March 5, 2007 2:18 AM programs where IFoos talk to IBars but there is only one
implementation of each interface!
Yeah... a good rule of thumb IME is not to try abstracting until you've got /two/ examples.
* Because the payoff isn't there,
* Because you'll probably not get the division right between what ought to be in the general interface and what are in fact just characteristics of a specific implementation.
It's easy enough to insert a base interface/ABC later when it becomes worthwhile.
John on March 5, 2007 2:23 AMJeff,
Thanks for your response. I get a lot from your blog and the responses I read there. RSS is cool.
I can't go into too much detail, but the app was written to handle 100-200 different types of flat files, some with vanilla schemas and dozens with rocky-road-and-sprinkles schemas (indeterminate number of fields, multivalued fields, odd delimiters, positional files, etc.).
Since I was new at this, and since I had read The Pragmatic Programmer and was all about orthogonality and DRY (to the extent I could adhere to them), I kept inheritance down to a minimum and a much more experienced programmer refactored my original code and made the inheritance structure very much more better. I learned a lot from him and another programmer I worked with.
Anyway, the app was written in VB.net, Framework 2.0.
The factory was to fetch the proper parser I needed for a particular file. Pass in string, get parser object through interface.
The template method was used because I was going to do the same list of steps for each translation (validate, parse, etc.).
One of the benefits (unknown to me when I wrote it originally) was that other programmers were able to use my object library to do some back-end validation and fixing.
I'm sure there were many more elegant ways of solving this problem (and I am sure I will read them later in this post). But the code works, it is relatively easy to maintain, and I have even written a code generator to make new objects easy to create.
The reason for the original question was: is it too simple a design? Did I miss something? Judging by your answer, I should feel better about it.
Thanks again.
Gene on March 5, 2007 2:28 AMEd wrote:
"The problem, as I'm sure is documented elsewhere, is the crappy teaching phase driving home that "OO is about all about inheritance" when it's not. Inheritance is a powerful tool that is sorely abused."
agreed. i personally think OOP is far more about information hiding than inheritance. this problem is also due to a language weakness.
i used to program a lot in Ada, and i rarely had a need to use the inheritance mechanism of the language, because the language provided me with all the tools i needed for good information hiding and modularization. C++ for example, as many other OO language, allows information hiding _only_ by using a class. the language is missing a real module oriented method of programming and developpers uses classes to emulate it. this directly calls to derivation and inheritance hierarchies, because we are taught that classes exists to be derived.
looking back at programming language history, we can identify 3 trends, building on top of each others: procedural programming, module oriented programming and object-oriented programming.
procedural programming is what you are taught when learning algorithms. programs are built up of simple procedures calling other procedures. each procedure does one thing and do it well. C is typically procedural.
module oriented programming is the evolution of procedural programming: you assemble a set of related procedures and type definitions into a module. this provides information hiding and allows to ensure a strong structure of the program. a module, in OOP terms is like an interface, differing only by the way you achieve the derivation of the interface: in module oriented programming, you replace the source code of the implementation of the module. Modula-2 is the best example of module oriented programming, followed closely by Ada-83.
object oriented programming is the evolution of module oriented programming: you have the same tools as in module oriented programming but types and operations on a type are more closely assembled, and you have a programmatic way to replace the implementation of a module (now called a class) by another one behaving differently. C++ and Java are object oriented.
(of course, you can built a software using any of the three "orientation" given a language of almost any other "orientation", it is just a difficult, often manual, and error-prone process: C can go object oriented if you really want it to...)
generally, people need to use module-oriented programming, but the lack of support by most mainstream language of the day makes them rely on object-oriented programming instead, calling for all possible abusements.
rien on March 5, 2007 3:00 AMI read somewhere the following: "The difference between a terrorist and a Object-Oriented Methodologist is that you can try to negotiate with the terrorist". A lot of people that behave like you describe in this post make it come true :o)
Excellent post, keep it coming :o)
Cesar Viteri on March 5, 2007 3:37 AMEncapsulation and polymorphism are both far more powerful ideas than inheritance (interface inheritance excepted in strongly-typed languages).
When I worked as a programmer in a medium-sized IT shop, I saw far more people who didn't have good OO skills, despite programming in an OO language, like Java, than people who overused inheritance. We had people who simply made everything static, for example. Our hiring process was admittedly terrible.
coderprof on March 5, 2007 4:04 AM"The principles of object oriented programming are far more important than mindlessly, robotically instantiating objects everywhere"
As has been said for millennia: Do not follow in the footsteps of the Sages. Seek what they sought.
Reg Braithwaite on March 5, 2007 4:15 AMI don't know why people make such a fuss over objects, I really don't.
Normally objects works better using composition rather than inheritence, anyway, not always, but mostly.
A lot of the problems I see described here are similar to when I see people using UML, a stick figure a few boxes and lines and hey presto a full design that will describe the interactions of 3000 lines of code, I don't think so, a lot more detail please. Those three letters be they UML or OOP do not convey any special aura on the code. You still need to do a good job.
If people overuse features, then they are using them inappropriatly, presumably they don't know any better, or don't have the confidence of their own convictions. Or want to learn some new stuf and add it to thier CV/resume.
When push comes to shove, to me (and I seem to be in the minority here), there is very little conceptual difference in OOP code and non-OOP code, cetainly nothing revolutionary. It's basically conceptual integrity through high cohesion, low coupling i.e. encapsualtion and private methods and state. Polmorphism icing on the cake.
Oh and yes, the "object-oriented" bit of OOP, does not refer to modeling real world objects in code. You are modelling conceptual objects in code, when was the last you could examine the metallurgy on your car object. You can't, it dosn't have any, not a real object, a conceptual object.
Clarity is king.
If you can look at any piece of your code and it holds together conceptually, fits in your head and presumably does the right thing, your home free.
So in conclusion, OOP its just stuff like anything else, stop getting your knickers in a twist.
David Hutchinson on March 5, 2007 4:36 AMWhen I studied computer science at the university of Oslo, we had a lecturer called Kristen Nygaard who actually invented object oriented programming. He invented OOP for a language called Simula as a technique for modeling real world objects and beheaviours. You do not have to program OOP in Simula, like in java.
Thomas Flamer on March 5, 2007 4:49 AMOnce, years ago, I got called in to salvage a C++/C project. The original developer had written a web of 300 classes (for an inventory-management system) with a *mean* of about twenty lines of code each; massive inheritace, aggregation, slam-bang, you name it. He had a jerry-built class browser which he used to "manage" it all. Quite a feat of solo engineering - if it had worked worth a da?n. When he left (willingly or otherwise, depending on who's talking), we discovered that about 50 tiny classes didn't even show up in his browswer, because as the comments said, "you should know this stuff is there already".
Blech.
Two months later, a system with the required function, half the lines of code and ~15% of the class count went into production. Last I heard (about 3 years ago), that's still the base for their production system. I never heard of the original coder again; I keep expecting to trip over a micro black hole somewhere formed when his navel-gazing recursed catastrophically. Occupational hazard for OO newbies, I believe.
Jeff Dickey on March 5, 2007 5:14 AMA good expansion for "POO" would be useful.
Poorly Organized Objects ?
Procedural Organization Obfuscated ?
There should be a term for abusing OOP in particularly horrid ways, and this is as good a candidate as any.
Anonymous Cowherd on March 5, 2007 5:15 AMAs one of the commenters said using Test Driven Development is one of the best ways of developing code.
First think of the way you'll use it and than code it.
Agree with the post, but PFO seems a better acronym.
John on March 5, 2007 5:35 AMI Found Free PlayBoy Girls, you need view this.
Absolutely FREE PlayBoy Penthouse:
http://www.girlsupdates.com/gateway.php
goblin on March 5, 2007 5:59 AMGreat post Jeff.
Developers who write clear, simple, maintainable code satisfy these criteria:
1. They can program (as you pointed out last week, many can't)
2. They must directly support in production the code they write
3. They are very close to their users -- physically, organizationally, empathetically, whatever
4. They expect their code to be used for the long term (not a throwaway work)
Of these, my peeve is #2. It's amazing how unrecognizable your own code can be six months, a year later. If you have to support that code, if users can walk over to your desk a year after you wrote it and ream you out because your program doesn't work -- then you're MUCH more inclined to focus at the start on writing it well, so that it can be easily read, understood, and maintained.
Life in OO land would be far less stressful, and far more productive, if folks had listened at the beginning. Do Not Build to the Bean Paradigm. But that paradigm has taken hold, and much of the Design Pattern stuff is an effort to deal with this. If the profession had listened to Holub/Stroustrop/Arnold/Meyer and implemented OO as objects having capabilities, rather than simplistically as data and method, we would be far better off. But that didn't happen.
BuggyFunBunny on March 5, 2007 6:08 AMI like one of the quotes in Damian Conway's Perl Best Practices:
Always write your code as though it will have to be maintained by an angry axe murderer who knows where you live.
dnm on March 5, 2007 6:11 AMI agree with most of what you say here, but I believe one of the prinicples you list is the root-cause of all OOP evilness: code re-use.
I have seen many projects collapse under the weight of OOP simply because the developers were trying to make everything re-usable. Making code truly re-usable take a lot of thought and effort and there simply isn't enough time for this on most projects.
If we stop advocating code re-use (for general developers), more OOP projects will succeed.
Jeff M on March 5, 2007 6:16 AMI like to think of strict OOP as being extremely important from the outside looking in, and much less important from the inside looking inward. A good OO API is important for those who use your code. Well designed divisions of responsibility is important within the private code of your assembly is important to reduce complexity in code maintenance and increase reliability. Its very similar to views and SP's in databases. You provide a very rational, straight forward interface for others to access what they need. It doesn't matter that behind that interface is a completely different storage paradigm.
Captcha: orange. Again, and forever more, amen.
Will Sullivan on March 5, 2007 6:20 AMMy thoughts:
1. Your programming language doesn't need to enforce public/private/protected members of objects. Just make everything public and yell at your coworker and check in a bug report if they use the interface wrong.
2. In general, total program correctness is an impossible task (the Halting problem), so don't worry about whether or not you can prove a program is correct or not. If your test cases are well written, you'll have pretty good confidence that the program works correctly under a wide range of circumstances.
3. There's no reason not to mix OOP and procedural programming. Similarly, there's no reason not to mix high-level languages and low-level languages. Use high-level where it makes sense (user interface code, et cetera). Use low-level where that makes sense (speed-critical procedures).
Brendan Dowling on March 5, 2007 6:25 AMBut (and word to Paul Graham): you can prove anything by oversimplifying the issue. I'd like to see the example problem in where " something a Lisp hacker might handle by pushing a symbol onto a list becomes a whole file of classes and methods."
On the whole, I'd also be a lot happier if the Lisp hackers and Perl goons would keep their worldviews to themselves. What they do isn't like what I do, and vice versa. I don't pee in their pool, so they can damned well stay out of mine.
[rant]
Tell me, tell me, tell me--how does one determine program correctness in Perl? Answer: One can't--Perl does what Larry Wall says it does, however he says it does it, and Larry doesn't give a flying damn in a circus tent about correctness. Perl's almost an anti-language. What relationship to actual computer languages does it have at all? (And the notion of Perl "best practices" can be summed up in one sentence: DON'T WRITE IN PERL.
Likewise LISP--the business of business IS business--and LISP isn't. Example:
(let ((g (* 2 (or (gethash word good) 0)))
(b (or (gethash word bad) 0)))
(unless ( (+ g b) 5)
(max .01
(min .99 (float (/ (min 1 (/ b nbad))
(+ (min 1 (/ g ngood))
(min 1 (/ b nbad)))))))))
That's not real programming, that's BASIC written by ee cummings! (Yes, I realize he's dead, I'm making a rhetorical point.) How the Hell is that maintainable--much less _readable_?
[/rant]
mrprogguy on March 5, 2007 6:33 AMHey, you can prove programs are correct for a large class of programs. The "halting problem" invokes the loading of "any" program. While you can't prove EVERY program is "correct" or "will halt", you can certainly build your programs in such a way as to PROVE that it is correct. And test-driven development with OOP is very good for that.
GregMagarshak on March 5, 2007 6:36 AMI think its important to remember that OO is just a tool, and it is one that sits upon other programming "paradigms": procedural, structural, etc. In procedural programming we got things like subroutines and functions. In structured programming we have things stricter scope of variables (such as in if statements, loops, methods, etc.) In OOP, we have things like classes, properties, inheritance and interfaces. These "add-ons" to what came before, are there to solve specific problems at specific times, but we should NOT forget the basics. Many times, I see spaghetti code that ignores good, old fashioned, basic procedural and structured programming practices. This isn't a lack of OOness, but just bad procedural code.
I too have also seen a few projects where the developer blindly made an object for every possible thing, but this is rare. Your comment about overuse of interfaces is well noted. I kind of think of OO as sharp tools--they are more complicated to use but are meant to solve complicated problems. Developers need to understand that there are trade-offs to using these tools and that you should only use them where they're a good fit. If you have a simple problem to solve, use a simple solution. I've also heard of a developer team making an object for every stored procedure in their database, which also seems overkill to me (whouldn't a method more closely match what a stored proc does?)
On my first OOP project, i went crazy with inheritance and it cost me. I was the stereotypical handy man who only had a hammer and saw every problem as a nail. As I matured, i find that i use inheritance much less and only in situations that seem to truly need it.
That being said, I love the OO mindset, and I love the tools that OOP languages bring to the table. I would say lets not discount the tools just because they are abused by people who don't know better.
Finally, a word on the impedance mismatch thing: yes, if you don't have a decent O/R Mapper and have to do that work yourself, the impedance mismatch is a productivity killer. But is that a fault of OO or a fault of relational technology which has dominated the database market for years? (Just as in the same way that OO has dominated the programming language market.) I think its time we merged these two paradigms together somehow with OO databases or something halfway in between object and relational. I know its been tried before and failed but is that due to a failing in the concept or just bad marketing? Shouldn't database have a concept of inheritance? Shouldn't i be able to have one table reference another without having to define primary and foreign keys? This is repetitive work that i do over and over and i think its time that the database software did it for me. Note, i'm not saying that you shouldn't declare primary and foreign keys, i'm saying the software should do it for you, automating it somehow.
Fregas on March 5, 2007 6:48 AM"i like old VB but the new OOP VB.net piss me off."
People coming from a VB background would be more likely to make these sorts of comments.
Diego on March 5, 2007 6:48 AMJeff, THANKS for writing about this topic.
I call this the "Huh?!" factor. Code should make you smile with enlightenment, not scratch your head in befuddlement. I'm sick of developers trying to prove how smart they (think they) are by making things needlessly abstract and complicated.
Once they can code their way out of a paper bag, the next thing they need to do is learn to find JUST THE RIGHT LEVEL of abstraction for the situation at hand.
http://bobondevelopment.com/2007/03/05/absuing-oop-over-abstracting-and-the-huh-factor/
mrprogguy,
I love the ee cummings comment. That was funny.
As for coding in Perl, if you look at things from a purist point of view (strongly typed languages that are compiled rather than interpreted, etc.), then Perl is a hard language to witness. For example (my Perl is rusty, so forgive):
sub foo {
my $arg = shift;
#What, pray tell, does shift do? I know, but do most programmers?
#or this
my $integer = 1; #holds the value 1
$integer = "moo"; #now it holds the string "moo" - weakly typed
#or even worse, evaluating the following for true or false
my $test = 0; #false
$test = 1; #true
$test = "zero"; #a string, therefore true
$test = "0"; #a string, therefore true
$test = "NULL"; #a string, therefore true
$test = undef; #always false
$test = ""; #empty string, therefore false
$test = "false"; #a string, therefore true
}
Perl allows all behavior, and due to the concept of entropy, or at least cynicism, most behavior is bad. Worst of all, Perl allows for very deep obfuscation, giving rise to the rite of passage for a Perl hacker, the JAPH (Just Another Perl Hacker). http://en.wikipedia.org/wiki/JAPH
But as naughty as Perl is, if the coder has self discipline, he or she can create orthogonal libraries, etc., and make the code sane and easy to maintain. And as I have been taught, when you need a shovel, grab a shovel, not a backhoe. Perl is great for scripting and such. It also has a rich set of libraries obtainable from CPAN.
And, you can even do object oriented programming in Perl. :)
Gene on March 5, 2007 7:20 AMThis whole thing entirely depends on the application you are writing.
If its a small-medium size app which has limited scope and scale then sure, breaking some style consistency is ok (again depending on where that is too).
For a larger application or framework, breaking a consistent style is very bad imho. It throws off other developers who are trying to use/read your code and turns it slowly into a big spaghetti mess.
Yes, creating interfaces for every object is overkill but not creating them isn't not creating OO code right?
Shaun on March 5, 2007 7:24 AMYou know, honestly I thought POO stood for "Programming-Oriented Objects". Here's how I broke it down in my head:
Object-Oriented Programming is when you program for the objects themselves. All your code is centered around creating objects that inter-co-mingle (I love that non-word) correctly and fluidly. Often times speed and efficiency are sacrificed for the sake of a pleasing source code base. Basically, it's when you use C# like a mantra.
Programming-Oriented Objects are what you get when you take an OOP language and hack at it like you're programming in something like C. We're talking using the low-level stuff that has almost no business being used in a high-level language. It's like when you wrap C libraries to something like C#, Python or Ruby. It's like... you can do it... but why the hell would you want to? Aside from adding functionality you wouldn't have otherwise had (often times defeating the purpose of the language).
Anyhow, that's just what I thought off the top of my head. Your explanation works, too. :)
Jae on March 5, 2007 7:32 AMI think this can be summed up very easily. Bad programming is bad programming no matter the language or the technique used. VB has a bad rap because so many bad programmers coded in it. C had lots of good programmers in the beginning. Not use why in either case, but still true.
OO can be equally bad. A language or technique is neither good or bad. Bad use or implementation of them are however bad. Programmers should be aware of the strengths and weaknesses of each that they do. If they don't then can they really call themselves programmers. I would say they are just coders. Programmers use the strengths from languages and techniques to reduce the weaknesses. If you don't then you are just a coder pretending to be a programmer.
Eric Turner on March 5, 2007 7:57 AMI just want to work with and for people who care about the long term aspects of their application.
And while those who care about quality, sometimes care so much, that no work gets done, or that's not about how can we work smoothly together, but whatever they prefer.
I mean i am willing to adjust to their needs, why can't that be mutual.
Craig M. Rosenblum on March 5, 2007 8:05 AMlol. i stopped reading this when i got to the "this image has been removed due to high bandwidth usage.
i would think that you could maybe, just maybe, pay the $2 a month for a flickr account.
Darren Kopp on March 5, 2007 8:08 AMInteresting. One reads your post and is reminded of comments I've seen before about how one exceptional CuLISP programmer can run circles around a C++ or Java programmer in certain types of productivity, but he will be behind his fellows when it comes to maintenance.
The 'Universe of Discourse' blog you pointed to is also interesting. Every once in a while I think that there has been an 'end of programming language evolution' reached; I've been wondering whether tools for Java would eventually become so varied in their depth and usefulness that pre-generated and wizarded Java would just outrun the other options as far as productivity was concerned... One can point to the entire 'AJAX as fast and easy as possible' movement as an implementation that attempts to address problems and inefficiencies created by design flaws.
Java builders are getting continuously more effective... It remains to be seen whether there are big enough efficiencies available on a broad base of problems to warrant a revamp of such a large install and training base.
Dylan Brams on March 5, 2007 8:29 AMUnfortunately any tool is only is good as the individual(s) using it. Simple, clean, properly decoupled OOP with flat hierarchies does wonderful things.
Plenty of paradigms are inevitably abused so much in practice that they gain bad reputations. The one thing many coders would do well to be aware of is that every line of code should be part of a thought out whole. The real problem is as it has always been - programmers who spew out code at a relentless pace creating a nest of dependencies and bugs so thick as to die under their own weight.
In my career I have seen spaghetti and duplication of code and concepts in all of its ugliness in a dozen languages. It's always the worst in the language that is popular at the moment. Mediocre coders write mediocre code and abuse/overuse elements put in place to help them. This was true in assembly, C and certainly C++/C#/Java. Currently some new languages are more exempt because performance limits the code spew that can be generated. As those language implementations get faster this problem will appear in spades there as well.
For most people constraints are good. We could drive at 120 mph on the highway but there is a speed limit to keep us from being reckless. Programmers should be rewarded for simplifying logic and extending functionality at the same time. There is a reason many software projects die under their own weight over time of self-strangulation.
Keep things as simple as possible and no simpler to fulfill requirements. If you're spewing out code someday you might actually be forced to figure out what that code does. A well thought out less almost always beats a poorly thought out more.
Steve Riley on March 5, 2007 8:30 AMObjects can be an incredibly powerful way to manage large-scale programs. Then again, objects are one reason programs *get* to be large scale: OOP code is bloated, especially in C++/Java/C#.
When I work in C#, I would kill for the ability to take a private variable and it's public property wrapper and use a Lisp-style macro to make a one-line declaration out of the whole damn thing. I mean, jeez, how many times do you have to type the same old boilerplate public int Blah { get { return _blah; } set { _blah = value; } } ? Then there's the endless stream of type declarations and casts -- I mean, the functional languages like Haskell and Ocaml are smart enough to infer types, why can't C-style languages do this?
JavaScript seems to be universally loathed for some reason, but the mixed object-functional idiom you can use pretty easily (and the dynamic typing) makes coding so much simpler. JavaScript code seems to take me less than half the lines and be more than twice as readable than C#.
Maybe for my next job I'll switch to Python or Ruby -- or maybe I'll try to jump all the way to Haskell.
AN on March 5, 2007 8:57 AMIf I were to start a link blog, I think 90% of the links would be posts about how you should write your programs to solve the problem you are presented first and worry about proper design second. That doesn't mean you should write hard to maintain code. Strictly OOP doesn't necessarily equate to easy to maintain code. The other 10% would be links to Penny Arcade and Achewood comic strips.
Scott on March 5, 2007 9:01 AMi would think that you could maybe, just maybe, pay the $2 a month for a flickr account.
Thanks for the feedback. I'm experimenting with different ways to handle images at the moment..
Jeff Atwood on March 5, 2007 9:15 AMYeah, and then you've got that whole multi-threading thing to deal with on top of OO-type programming.
Jim on March 5, 2007 9:17 AMYour are right no with this one!
I write my code so it hides, is simple as possible, and is maintainable.
Client ask me to look at something I haven't worked on in 8 months and I'm back in the saddle in 5 minutes!
Mr_OOP on March 5, 2007 9:57 AMI agree - OOP has to be used sparingly.
Good rule of thumb: new object oriented (non-static) class should be created only if developer sees clear advantage of OOP approach in this particular case over "static methods" approach.
Have to agree with coderprof: in everyday practical terms polymorphism and encapsulation seem to pay bigger dividends than inheritance.
I think the basic problems is simply that OO is hard.
When you have done your 5 years of apprenticeship, hopefully you will have understood how to use OO.
Marcus Philip on March 5, 2007 11:10 AMOOP is very core to Frameworks, the .NET framework would be sloppy without it. OOP can be overkill but even the bad cases (one implementation of an interface) can be because the class needs to be remoted or shared for other purposes. Without OOP we'd still be coding VB MTS COM+, please god no....
There are benefits to calling code in certain ways as well. This is a test of .NET 2.0 calling methods based on MSDN sample from .NET 1.0.
http://i81.photobucket.com/albums/j223/drawkbox/NET20.png
Well I would argue that even bad over-adherence to OO is still whayyyy better than putting all your logic on one form and not writing any unit tests.
*Goes back to work on said application *
owen on March 5, 2007 12:34 PMCurrently I am the other programmer having to maintain code and fix bugs, and it is hell.
Overkilled OO is a nightmare, as is function blocks of over 300 lines of code that calls other similar lengthed function blocks which only get called from this one spot (and they contain functionality repeated elsewhere).
Code should tell a story in an fairly easy way. All the names should be well thought through. The sentences and paragraphs should not be to long. Don't repeat yourself. I repeat, don't repeat yourself.
In coding terms, keep you functions short, your classes focussed, and if a class will be an overkill don't write it.
Jeff,
I've been reading your blog for a while now. I quite enjoy tuning in every morning when I get to work and am sipping my coffee reading what you've written. However today I think that I have to disagree with you. OOP is great and I love it, when it's used correctly. I've seen time and time again where as you mentioned "inheritance hierarchies to be brittle and unstable" When you tightly couple software like this you're 100% right it becomes impossible to use. Impossible to refactor. Impossible to maintain or update without breaking 1 million other things in the code. It's worth noting that this isn't good OO. In addition to the principals you mentioned above OO, should be loosely coupled and each object should have a specific job. Even if you have tightly coupled Procedures in a Procedural driven language you're going to run into the problem of not being able to update or refactor code, add or maintain.
Yes as a software engineer I had the idealogies of OO driven into my head in school. Yet the first language I learned was C. What they didn't teach us in school was how to write good OO. OO that is loosely coupled and based on a core set of abstract interfaces that are well thought out to provide base functionality can be incredibly powerful. When you need aditional features making additional interfaces through almost a composition approach rather then an inheritance approach prevents you from falling into the trap of inhertiance brittleness. I find that in OO environments everyone wants to inherit inherit inherit. COMPOSITION is most often the best answer.
All that being said. OO is great but it's not enough on it's own, engineers need to be aware of Design patterns and other tools. OO is a design tool, not meant to stand entirely on it's own but be used in conjection with other principals, which together produce solid well designed software. Where needed I've incorporated procedural C code into my OO code when I needed the speed trade of and the low levelness of pure C.
I don't think it's fair that you take a technology and bash its down sides because people don't know how to use it correctly.
Cheers
Chris
chowell@pyxsinnovation.com
I forget where I read this now, but someone (it may have been pragmatic programmer) referred to bad OO code as spaghetti with meatballs. I have to agree with you (or of course, what _I_ think you mean of course :) ) though;
It is applying the principals of OO which is important. In fact I think it is understanding and applying the principals that gives the most benefit in pretty much every methodology from OO to DRY to XP. Without understanding the principals it seems that people leap on the bandwagon and apply it to everything without thinking.
I think what I am trying to say is that too many programmers seem to buy the shiney new tools, whether a methodology or programming language, and think that they are the answer to all of their previous problems and then apply them to everything without thinking about whether it is the right tool for the job. I guess that it is done because it is easier in the short term.
ps. another long time reader, first time comment, I guess this topic gets people fired up :). Keep up the great posts!
James Geall on March 6, 2007 1:05 AMThey used to call it spaghetti code, OO architects like to call it lasagna code however, most of the time oop winds up as ravioli code…
Rabid Wolverine on March 6, 2007 5:17 AMHey Brenda, what do you think your coding down iside those pesky objects? That's right, procedural code. All OOP does is put what is at the bottom level, procedural code in a neat little isolated package and gives you a methodolgy for defining an iterface between them. I belive the first guy to come up with this idea was Nicholas Wirth with Modula...
Rabid Wolverine on March 6, 2007 5:22 AMHey Rapi,
The fundamental distinction between object oriented programming and procedural programming lies in the concept of using if statements to differentiate behavior (procedural) versus using hierarchies to differentiate behavior (object-oriented).
Brendan Dowling on March 6, 2007 11:52 AMHi Jeff,
Long time reader, first time commenter. I really enjoyed this post, and pretty much all the comments on it. I've come from a VB4 - VB6 - C# background (there's a mix) and agree that with OOP you can make things exceedingly complex, however, OO-at-the-right-level is a very powerful thing.
I worked for an HR company doing payroll and personnel apps, and we catered for Oracle and SQL. It was only after two additional, more OO developers joined that I learnt the joys of the Factory pattern and abstract classes. That was tempered with the use of plain old strongly-typed datasets instead of the framework for data that two other developers had written because it was far, far easier to use and maintain.
The two "true" OO developers subclassed almost everything they touched, and insisted the other developers went through their objects for coding, when all that was required was just retrieve some data, process it, and output it to a file. Why use someone else's object (with all its caveats and foibles) when the exact functionality you require already exists?
And oh, the lure of re-usable code! "Let's make this generic," says the manager; "Can't we re-use this?", says another manager, neither of them realising that two apps which appear to do the same thing do it entirely differently behind the scenes due to customer requirements.
Reusability is a lofty goal - I remember being at a talk given in VBITS 99 in Chicago (ooh, get me). Microsoft Transaction Server had been released and I was attending a talk about it. The speaker was asked a question about the use of MTS and basically said, "Well, MS says to do it this way, and we need to stick to OO principles". The speaker replied with, "In development, there's always two schools on how to code: what is good and scholarly, and what works".
I always code as if an axe-wielding psycopath will be maintaining my code after I'm hit by a bus; the KISS principle also makes code less likely to break. There, I said it.
Great post, sorry for the long comment.
Kind regards,
Mike K.
Mike Kingscott on March 6, 2007 12:25 PMHi Jeff,
I came accross your site using stumbleupon, I suppose I was a part of your bandwidth blitzkrieg last week ;)
What do objects give us? Modularity.
What is modularity for programmers? Encapsulation and abstraction.
What is encapsulation and abstraction?
Encapsulation is the ability to separate our routines into separate "chunks" of logic.
Abstraction is the external interface of each "chunk" such that:
a) unrelated pieces of logic arent allowed to meddle with one another
b)the logic appears simpler from the outside of the "chunk".
Do you need a similar chunk of code to operate in slightly different contexts, or could you benefit from dividing the logic of your program into multiple loosely coupled components?
If not, you dont need them. OO is just another tool in the toolbox, with right and wrong times to use it.
At our business, we have two enterprise applications, one written in classic asp, and another written in asp.net C#. The .NET one uses NHibernate, an ORM mapper, and leverages extensive OO design patterns. The asp program is written using vbscript and stored procedures. Both have roughly the same amount of business logic intensity.
Guess which one costs vastly less to maintain?
Guess which one we have trouble staffing, because all the programmers quit out of frustration?
Which project would you rather work with?
No offense, but reading through most of these comments, Im convinced most of these people (eg: old school VB programmers) never learned how to correctly harness OOP to their advantage... maybe they had a bad initial experience with it.
Dont abhor or fear the concept if you dont have much practice with it. The majority of "good" programmers can clearly visualize the benefits of OO
-pete
Pete on March 7, 2007 1:15 AMPete, in regards to most people who hate OOP or seem to instinctively fear those 3 letters when they see them, I think that is true to an extent. Often they come from a VB background and they felt like they had it down and then .NET came out (I'm speaking very MS oriented, I know. People who came from a Java background might not fully appreciate this).
But, as I am sure many here agree, the VB6/VbScript to .NET transition was a needed shift for Microsoft. Those who made the leap and are thriving in the workforce are much, much stronger programmers for it.
I am one of those developers who came from a very procedural VB background and jumped across to C# a few years ago. I had an "understanding" of OOP and could have probably passed a verbal interview's worth of questions even. But, and this is sad in retrospect, it didnt start clicking for me until Visual Studio .NET and I started enjoying much better intellisense in my IDE (I think VS2005 is the greatest IDE ever, FYI. I might even arm wrestle you over that, though I have not checked out Borland tools in a while). What and which methods/properties were exposed and why, the time-saving and increased manageability found in inheritance, and portability of code across applications just became vivid to me because of intellisense. I started documenting my classes, methods and params so the next developer could have a little tag pop-up and say "Hey this is what I do, why, and how I should be applied". In the web dev world, its difficult to get that kind of reuse and documentation out of procedural code unless the developer goes to the actual file location and reads exactly what that block of code they're supposed to include does.
Most of what I do now is all ASP.NET so, for me often instancing an object and using available methods is almost like a replacement for an old-school #include directive, but that added structure makes maintence much, much easier. Plus, that added level of abstraction generally speeds up development once the foundation class coding is laid. BUT, thats just it. DONT lay down all of that code if you do not need to.
Knowing WHEN to use OOP is just as important as HOW.
The good book "Object-Oriented Analysis And Design with Applications"
By Grady Booch starts off with chapter 1 stating that OO is for managing complexity. I think the point well-made here is that OO taken too far only adds complexity.
No offense to all commentors, but I think Ed said it best...
"OO to me just provides a better way to hide implementation and abstract ideas away so I can create more complex, but logically simpler programs because I don't have to hold onto all the nuances of everything at once. It's no panacea, but it is nicer to work with when done right."
ok, we got OOP. we got POO.
Let's make another acronym: Perfect at Objected Oriented Progamming. (POOP). you can make this a certification that people can get by taking an exam or something. it can be sponsored or standardized by different vendors. You can be MCSPOOP, or Sun certified POOP. you can have all different flavors of POOP.(yuck)
Dave on March 7, 2007 9:36 AM"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."
According to me, the programmer Paul Graham is talking about in the above excerpt, is doing a great job and is being most productive. Code writing is not difficult. It is maintaining code that is difficult and accounts for 70% of development cost. So, if the programmer is writing elaborate comments about the code, he is doing excellent service for the programmer who will be modifying his code later on in the software development life cycle. It is right up with the spirit of POO that you yourself are talking about.
Cosmic Ovungal
I can relate 100%. I have worked with the same company for 6 years and recently started interviewing for a new job and what a disappointment it has been. I meet the manager and then they send in the guns, the 'technical' person, the "Architect". This new term "Architect", I try not to laugh in their faces when someone claims to be one thinking of George Castanza. They ask me how I go about designing software, and I ask, "which software" and the interview is over. I know they want me to have read the same crap NET book they read and explain some canned one size fits all oop process and they look at me like I am from Mars when I explain that the amount of design ceremony depends on the risk and complexity of each situation. Microsoft is moving technology so fast that "cutting edge" shops are tossing projects and rewriting them as new technology comes along. As long as deadlines are met, no one is the wiser to the failure of the product since there never is a measure or accountability before it is rewritten. In my last two interviews, I asked what their oldest set of code was and neither had anything older than a year and in both cases they said they would rewrite when VS 2007 comes out. So.. in this case, probably does not matter how they design their software since it is so short term.
Nameless on March 7, 2007 9:42 AMI'd say, just go for wordpress ;-)
seriously, though, OOP is great for re-use. It's like Mondrian vs. Pollock.
danny on March 8, 2007 2:50 AMThe methodology used by most programmers is not OOP, it is not POO, it is CAP: Copy And Paste. And remarkably, CAP is by far the most productive methodology. More programmers use CAP to get work done vs. any other methodology.
By embracing CAP, Microsoft used MSDN to utterly dominate the programming tools market. Nothing could compare to the vast volumes of examples that were provided via MSDN.
Today we see the open source world has embraced CAP even more deeply and is now, in turn, dominating Microsoft.
As for OOP, I've programmed long enough in the OOP world to know it is basically just another way of making noodle dishes. Usually the noodles take longer to cook and cost a bit more vs. procedural noodles. But they taste just about the same.
michael s. on March 10, 2007 5:41 AMI also have to say that I've been learning about IoC recently.
So far, I have discovered that "Inversion of Complexity" doesn't do much more than "Make Work for Object Brother". And really, if I were an object, would I want to be injected (by a stranger and not a friend, nonetheless) with dependencies?
The one thing they got right is that objects go into a container.
michael s. on March 10, 2007 5:49 AMVery good read. Our company is currently struggling to find a balance between OOP and code that a developer two years from now can support.
We have a person strongly pushing using all aspects of OOP regardless of the projects needs and others pushing back for a simpler approach to handling our coding.
In the end it's probably in the middle, but it's good to see others seeing it taken to a point where poor joe programmer starting with a company a year from now gets to sit down and figure out why this relatively simply project is so so complex.
Mark Hansen on March 13, 2007 1:38 PMOne does what one likes as an artist.
Most artists are unoriginal.
But most are motivated by others work.
OOP seems to resonate with many coding artisans.
It easy to be judgemental about OOP.
As you are here in this quote, "In my experience the best code, like the best user interfaces, seems to magically anticipate what you want or need to do next. Yet it's discussed infrequently relative to OO. Maybe what's missing is a buzzword. So let's make one up, Programming fOr Others, or POO for short."
In the end, it's all about the target audience and their concerns and desires. One's OOP is another's POO. Try to keep perpective. What will this all really matter in a generation?
Some excellent thoughts on the topic.
There is not much mention of multi paradigm programming. I suppose most people don't want to master everything a language like C++ has to offer. It frustrates me when people here of C++ they think only of OOP.
Chris on March 19, 2007 8:32 AMYo.....
I'm sorry but OOP or POO?
Thats the funiest fuckin title I have ever seen
Dan on March 31, 2007 11:05 AMListen, I'm NOT a OO snob or apologist, but when OO is done correctly, there's nothing like it. When the pointy-haired boss comes by the cube farm with a bunch of new requirements, a well designed OO project can usually handle all the new stuff seamlessly.
The problem is designing an OO project is an incredibly difficult/complex thing to do.
And judging by the comments here, you've all run across some really bad OO code. Unfortunately, the language and/or methodology gets a bad rap when the people have a hard with it. It's still up to the human; the best IDE, language, methodology, etc. will still allow you to cut off your fingers without warning. That and computer science courses in college aren't teaching objects... the cover of the book may say so but after page 1's "hello world", there's 500 lines of code in main().
I see a lot of myths from the functionally decomposed folks in the crowd:
1. "I totally agree with your point, as I see OO being useful for larger and long term projects. My own hatred of OO overkill is when the objects are so badly designed they can't possibly be extended."
OO has nothing to scope nor schedule... furthermore, if the objects couldn't be extended, then they aren't really objects in the first place. The use of the new keyword in and of itself does not == object.
2. "Some are just silly, like the Factory pattern, and truly are about working around an issue in the language (for example, the lack of classes as first class object in C++, where you could pass a reference to the Class object instead of a function pointer to the factory)."
That person is not writing OO code and the factory pattern is used incorrectly if you honestly think this.
3. "you know, put some code here that we can jump to from a bunch of places, putting the return address over here"
A true OO project does not return values... the objects should know where to get it. Unfortunately, and I'm guilty of this, mutator/accessor methods have become pervasive and associated with OO code but that is the wrong way to do it. And yeah the language lets you do it but the language also has the "goto" keyword but I don't seem anyone using that anymore.
4. "Then again, objects are one reason programs *get* to be large scale: OOP code is bloated, especially in C++/Java/C#."
Hardly OO's or the language's fault... sounds like a developer trying to write top-down code in an OO language. Well defined objects are hardly bloated.
5. "I mean, jeez, how many times do you have to type the same old boilerplate public int Blah { get { return _blah; } set { _blah = value; } } ? Then there's the endless stream of type declarations and casts -- I mean, the functional languages like Haskell and Ocaml are smart enough to infer types, why can't C-style languages do this?"
Because your example is NOT OO code... that's very functionally written; the return type is a dead giveaway!!!
6. "I had an "understanding" of OOP and could have probably passed a verbal interview's worth of questions even. But, and this is sad in retrospect, it didn't start clicking for me until Visual Studio .NET and I started enjoying much better intellisense in my IDE"
This is NOT a personal comment but the IDE does not make someone a better developer. If you're in VS2005 and banging away on the dot or ctrl + space to see what interfaces and methods are available to your types, I betcha you're still writing very procedural code.
Finally, and for goodness sake... don't mix the two. When you mix procedural and OO, cohesion and encapsulation start to suffer very quickly.
I for one love oop. I have long been a procedural programmer with experience in assembly, c, and php and never used any comments. I detested oop but once I used javascript I fell in love with it.
The idea of working with objects and manipulating them is amazing. It allows easy modifications and upgrades to the software I develop. I also think oop is the way forward. If we keep thinking of tax then we would all be programming in assembly language.
People used this same reasoning during the migration from assembly to compiled language. But today no one even thinks of coding in assembly. As computers get faster, the extra load will soon not be noticed. So like I say: I LOVE OOP. LONG LIVE OOP.
Zeeshan on June 6, 2007 10:54 AMJavaScript is neither Java nor OO. Try again!
WTF??? on June 11, 2007 2:24 AMquote Jack on March 4, 2007 10:13 PM
i love VB because i don't have to code it the OOP way but how do you reuse your code if you don't use OOP?
You can code in a procedural language like you have OOP. Put the data structures and the functions that use them in a header file (dreams of C). If you need that "objects" functionality, include that header. Viola the code is reusable. For the most part, you own the code that your reusing, so if you need to add a function to that "object" add it to the header file. Use a revision control system, and document, and then document some more.
Something like:
// build with version 1.1.3 of this header file
Should help when the user gets errors saying the new function isn't available.
Mike on September 6, 2007 1:56 PMQuite fun. I often find that a lot of OOP ends up looking like POO. Thanks for this post, I thoroughly enjoyed it.
Jeff Davis on April 25, 2008 8:52 AMThank you, gentlemen. I am not a programmer, although I want to learn to do so, and I detest jargon that obfuscates and stands as a barrier to learning how to program, and that is exactly how I see all OOP discussions. I got an 'A' in a college VB6 class, but my gut reaction to even the mention or thought of VB6 for years was the deepest and most profound hate that I have ever experienced towards anything in my life.
I pride myself in being able to take the very complex and to accurately reduce it to the very simple. I learned the skill in law where I would address complex arguments and take them apart and recast them into their simple, accurate substance. (See, e.g., Pratt v. Sumner, 807 F.2d 817 (9th Cir. 1987).)
VB6 is unintuitive garbage. Only an utterly artless soul would call it intuitive. Think Apple iPod, and you have intuitive, think of a digital watch that needs to be reset after the instructions are lost, and you'll realize why I never wear one. If I could tie Bill Gates to a chair and torture him for a week or so, it would not be about his unfair monopolizations, it would be about VB6.
Since then, I've had a softening after learning and using a little VBA to write text in Word for an HTML file rather than writing every line in HTML by hand.
However, the language I've actually been able to do things with has been javascript, and, but for the browser-specific quirks, I like it. It's relatively easy to understand and relatively easy to use creatively. From what I've read, it can be used OOP style, though I wouldn't know an OOP if it hit me in the eye. My intended strategy was to use javascript and the browser for rapid application development, and then to learn a real language when I've got the logic down and want to create apps.
However, with the learning curve of using any of the so-called real languages, I'd prefer to choose narrowly and well, and so I enjoyed reading your posts, all of your posts. You showed a lot of variety and a natural use of your jargon rather than the stiltified text blobs of nonsense that I simply cannot read.
Although you have not helped me choose a language to study (I'm leaning towards Python), you have helped me see some of the problems with OOP thinking in general.
Thank you.
Ray Donald Pratt on April 25, 2008 11:32 AMOOP is an excursion into futility.
It is oversold, anbd rarely are the benfits worth the costs.
Far from making code clearer it generally adds to obfuscation.
A methodology or tool, adopted with religious fervour, cannot substitute for good design and high quality coding.
What is required is clear thought, clear structure, well chosen names, and precise, accurate, and pertinent commenting.
There is nothing that can be done in C++ or Java that could not be done quicker, more clearly and just as effectively in C, and in other problem domains completely different languages such as LISP and Prolog are in any case more appropriate tools.
The drawbacks of OOP become most apparent when trying to maintain an OOP-horror. The sequence of procedure calls and values of variables was easily tracked in old-fashioned C. Troubleshooting is an order of magnitude more difficult in C++ or Java.
Tom on January 21, 2009 7:42 AMIMHO, OOP is awesome.
Not because of inheritance, or interfaces, or any of the other feature-candy. OOP is awesome because it's a great tool to describe things.
To make OOP easy, here are a few concepts to add to POO.
OOP IS procedural:
...as long as you want it to be. Every OOP program starts from static int main() (or the equivalent). Until you actually instantiate a class, this is still a purely procedural program because it is going from line 0-n.
OOP IS modular:
Don't mash all the parts of the program into one massive class. Create utility classes to move the implementation of the parts out if the main program. IE. The static int main() is just a an executive function that calls the shots, where separate static utility classes are the departments that handle the details and resources of the requests. The executive's time (amount of code) is too important to worry about the menial details of the rest of the organization. OOP programs usually take fewer lines of code overall to handle everything but at the sacrifice of becoming more complex so they need to be managed appropriately. IE. chew before you swallow.
Most abstracts are Scholars and Artists not Inventors:
Unless you're trying to prove you're smart (and like wasting other people's time) abstracting parts of an OOP program is a waste if time. 95% of the time, anything in life can be described in simple terms. Apples are red. Dogs bark. Traffic light colors are red, green, and yellow, a Car's acceleration can be described by... s***. Too complex to be described in simple terms so it needs to be broken down to finer levels of granularity before it can be addressed. Maybe throw a little inheritance-foo, a physics utility class (for reuse-ability) with static functions describing the fundamental math, and it becomes do-able. IE. Don't create a Pollack painting and expect enlightenment. Create technical drawings/models first when you're designing an aircraft.
I think that the issue with OOP (and why so many people hate it) is not technical, it's sociological. I learned OOP on my own out of the classroom, but I could imagine professors getting their panties wet contemplating all the possibilities of uses for all the constructs built into modern OOP languages. Of course all of features sound great in a theoretical aspect but realistically, most are useless the majority of the time. Use OOP for it's intended purpose, to describe things, properties of things, and characteristics of things. Don't inherit a human class from a cell class or you'll have a lot of unnecessary crap to explain in between.
I went from a self-taught web dev background (HTML/CSS/JavaScript/PHP/SQL) to C# and it took me less than 6 months to get comfortable with all the fundamental constructs of OOP (Except interfaces which IMHO think are pretty useless so far). I understand why most people are frustrated with OOP. Most study materials are full of abject theory and poorly written examples. If you're learning C# check out http://www.blackwasp.co.uk/CSharpFundamentals.aspx. I'm not affiliated with this site but I couldn't begin to explain how much it has helped me. It's like the w3schools of C# (but written better).
For the procedural programming purists out there who don't benefit from OOP, do one thing and do it well. Procedural no doubt has superior benefits of performance and simplicity for back-ends like servers, kernels, console apps, and services. But, for event driven applications like GUI front-ends, file system tools, database ORM, and operating system components I'd much rather use OOP.
Evan Plaice on March 3, 2009 2:25 AMIf I'd studied rhetoric, I'm sure I could have named the device used in this sentence: I'm not a fan of object orientation for the sake of object orientation. Regardless of the appropriate label, though, isn't it so that the opposite position is clearly impossible to hold on to? Everything we do is a means to an end.
Einar on March 17, 2009 2:31 AMSadley many programmers do abuse objects, but this just sounds like a bunch of old time procedural programmers that are having a hard time catching up.
Dave on March 18, 2009 1:51 PM1. Be organized classes and write the application to allow load and display all kinds of image files with the extensions in the following categories. Jpg,. Bmp,. Dib,. Gif. Programs that change the image as horizontal turn, vertical (mirror), dial 900, the gray level to get the sound, get the wrong picture of the two special functions and stored into different (but still one of the significantly above).
Requirements: The thought by the audience. Can be programmed in the Windows environment. Do not use static function as eg in the theory, does not switch, in the case.
2. An input directory is a folder or a file, a directory of many input folder. Drive is a special case of the directory. Be organized classes to perform concept computer, disk drive, folder, file with the relationship as over. Write the application for permission to view the content of the object type as similar functions of the software Tree NC.
3. For the types: circle, ellipse image, the polygon, crescent,'s wings, rhombus, parallelogram, trapezium, rectangle, square, triangle, triangle square, square triangle needed. Write a program that allows applications to create (or enter) the two pictures in one of the above. Notice in two pictures that are not intersecting, if any color to the bowl and the dark sea of the interface. The user can press the arrow keys to move one of two pictures, the +, - to zoom out one of the two pictures. Programs can work with all kinds of equipment in different graphics modes, text mode (each a '*' is a moral pixels). Program can zoom to pixel morally, from the graphics mode to text or vice versa, users do not see the object to be exhaustive
4. A road of many road Polyline (line), each line can be a straight section (Strait line), and (ARC), or a bezier polyline. Organization of classes necessary, establish the relationship between class and write a program that allows to create polyline, create a copy of the polyline, zoom in, zoom out, turn polyline, polyline separation (separation of the polyline in the a polyline into the road (line, arc, bezier), define two functions have polyline cross or not?
That's a very nice post! I'm french and I googled this php poo best practice logical class which brought me here... That was a very interesting experience to read this, and the comments extended the object of debate, which is even better ;)
Many people think tend to believe that (I'm talking about PHP but it can be true for various languages) OOP in PHP is best practice. It's not properly thinking, because OOP itself brings its own set of best practices to have in mind when using it. Though when you start mastering it, you win some time, I ensure... This leads me to speak about frameworks, which is out of topic, but I learned OOP thanks to a PHP framework, and I wouldn't revert back to no-framework. Or I'd need Ritaline.
Benoa on May 13, 2009 11:33 AMi love OO programing i am 12 and i am already working on threads, networking, encryption (jsse[java secure socket extension]) and i am just about to start data structures. I know my sight is a little pathetic but i really don't know what to do with it. for suggestions email me personally at kitten_elrer@yahoo.com
James Erler on August 13, 2009 8:24 AMOOP is for humans, not for the machine. Does the machine care if your if you have implemented inheritance? Not really. If your code is perfect OOP does it run faster?
Pentium Processor: "I just love running OOP code, it feels so good!"
OOP is best for organization of code and should be used as such. When using OOP, ask yourself, do I really need a interface or abstract class, do I really need a base class. Sometimes it is just better to write just to write the damn class.
OOP can simplify but it can also abstract and obscure.
Jon Raynor on February 6, 2010 10:03 PMThe problem I have with many arguments against OO is that they seldom are specific, but usually very generic, and hence they become hard to evaluate. Take the first comment by Paul Graham:
"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."
Concerning the first part of this comment: is it a problem to write:
class Math {
...
}
around your math functions?
Second, he says:
"Something that a Lisp hacker might handle by pushing a symbol onto a list
becomes a whole file of classes and methods. "
what? - what could he possibly mean here? Lists is a library class in Java.
Allright. So much for that comment.
The next comment is that of Eric Lippert:
"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."
No, you don't need to write abstract classes and interfaces. In fact, most programmers don't do that even for big programs.
I have this impression that people arguing against OO do not program OO themselves, and observe fragments of code, to which they react as if these fragments were proper representations of how OO code is normally written.
Their arguments are based on existence proofs: there is exists a bad OO program,
hence OO is bad.
If there is a "good" way to do OOP and most are doing it the bad way in practice, then perhaps OOP needs to be redefined. The practices and techniques that make the "good way" need to be isolated and renamed something else. It's not OOP that's good, but apparently a sub-set of it, but nobody can define and document "it"; only say, "I'll recognize it when I see it". That's not good enough in the age of openness and science. That's Alchemy-Oriented-Programming.
I personally find set-theory, or some variation of it more promising. Associations don't have to be hard-wired that way, meaning you don't have to get the design perfect up-front in order to use it effectively. OOP's associations are too hard-wired, and not searchable and query-able in a meta kind of way, except with spaghetti class browsers. Perhaps the "fight" over OOP is graphs (pointers) versus sets.
The Functional Programming people are giving OOP a run for it's money. In my opinion they are just as zealotic as the OOP crowd, but it's nice to see visible competition to OOP out there, even if it is run by other zealots. Fight zealots with zealots? IT is so not science.
Testy Tester on March 27, 2010 2:08 AMI learned C in 1992, never liked it . In 1998 i programmed an extensive algorithm, that grew a neural network using genetic algorithm and really fast regression..I programmed it in C++. I was new to OO. It took 6 weeks of reading up on C++, 6 weeks of design and 6 weeks of implementation. it worked, it performed really well and fast on any data I threw at it. I think if i had to write it in C or structured programming language, it would take 6 months min..and would have 0 reusability. I dont even want to think about it..
I have an estimate of the structured time, because I wrote parts in Matlab and had to piece the things together , so i have an idea of how long things took in an interpreted envirnoment..which is fast.. but not powerful.
Amongst other, I used a composite design pattern, going 4 levels deep. Try and do this in structured programming.. is like a recursive function , where you would have to pass whole trees of data down.and each element would need to know which part of the tree data it can change...would be a nightmare..not that it can't be done..and with powerful libraries should be possible..but back then the internet had only just begun and such libaries were few in between and the best ones were all written in C++ in any case..probably for the same reason. Now I would use C# because of garbage collection etc..
Yes horrible OO is probably like structured code with GOTO, but good OO is sometimes like magic compared to structured.
The comments to this entry are closed.
|
|
Traffic Stats |