4 ms·
There's nothing intrinsically wrong with OO programming. I find that data tends to map very naturaly on to objects. However, the biggest problem I've seen with
by arockwell 18y ago
There's nothing intrinsically wrong with OO programming. I find that data tends to map very naturaly on to objects. However, the biggest problem I've seen with OO is that people are tempted to build over-engineered solutions to simple problems. Java's EJB 2.0 spec is a great of example of OO design gone wrong (long story short, you have to implement an obscene amount of boilerplate code to get even simple things done). Anything that basically requires you to have an IDE to write your code for you to get off the ground is extremely counter-productive.
I think Java is particularly bad in this department, since I think it often really encourages with the "Let the IDE handle it for you" mentality.
- aston 18y agoYeah, but "let the IDE handle it" is a perfectly valid way to code. When you want to run water to your house, you don't hire someone to design new pipes for you; you use the ones pipe companies kick out. The boilerplate is just plumbing your IDE manufactures for you. The only difference between it and the magic that happens in dynamic languages with stuff like RoR is that boilerplate code is explicit rather than implicit. I prefer the former, truthfully, so I don't have to understand the whole stack to work on a small piece of the code.
- Zak 18y agoGood abstractions don't require you to understand the whole stack. Effective use of a function, for example requires you to know: * What the valid arguments are * What will be returned * What, if any side effects calling the function will cause * (sometimes) What resources the function will utilize Use of most other data types is simpler. Your framework or library should give you this information in the documentation. If your development environment is reasonably friendly, it will give you the arguments, and in many cases, you'll be able to guess the rest of it based on the function name. If you have to RTFS to figure out how to use your libraries, something is wrong. Institutionalizing that by always putting the source right in front of you is a Bad Thing.
- aston 18y agoI'm not arguing against abstraction. I'm arguing that explicitly wiring between components is better than implicit. To make this concrete, take the example of implementing getters for a class in Python. If my class has four fields class GetterDone: a = 1 b = 2 c = 3 d = 4 I can do something like this inside the class to implement getters: def get_a(self): return self.a def get_b(self): return self.b def get_c(self): return self.c def get_d(self): return self.d Or I can do something like this: def __getattr__(self, attr): if attr.startswith("get_"): return lambda: getattr(self, attr[4:]) raise AttributeError The latter does a good job of eliminating boilerplate, but at the cost of making it near impossible for me to find out how get_a() is implemented (assuming this was buried in a huge codebase).
- lisper 18y agoOr you can just realize that get_X is the Wrong Thing and you should just write GetterDoneInstance.X instead.
- aston 18y agoGreat job ignoring the substance. I thought it'd be better to come up with an unrealistic but simple example rather than to paste in the source for Pylons... Just play along and imagine a more complex world. If it makes you happier, pretend the getter is intended to return the string version of the numbers or some other operation that would make just using instance.a wrong.
- lisper 18y agoBut using instance.a is not wrong because you can override __getattr__. And if overriding __getattr__ is not the right thing then what you are writing is not a getter. Under no circumstances is it justified IMHO to write a get_X method. (And if your language doesn't let you override __getattr__ then you need a better language.) IMHO of course.
- DougBTX 18y ago
- arockwell 18y agoIf the code is so simple that I can hit a button and have my IDE generate my code for me then I really question why I need to write the code in the first place. A simple example of this is generating getters/setters. Autogenerating the code works great 99% percent of the time. The problem comes in for that 1% case where a non-templated getter or setter is needed. That special case is easy to lose track of in the forest of automatically generated code. Groovy solves this problem by automatically generating all of the getters/setters for you, but if you need to you can still override the automatic definition with a specific implementation. I won't argue you with that too much magic can be a bad thing. However, for the code I typically generate with my IDE I really think I'm wasting time and bloating my code.
- DanWeinreb 18y agoExactly. If your IDE can just generate it, then why is it needed at all? And, as I said, it makes the code harder to read. You have to look over all the boilerplate and see if it's all exactly the usual boilerplate, or whether one or two methods in there were manually improved. If the IDE has to generate it, it means that the programming language is expressing your wishes at too low a level of abstraction, rather than more-directly reflecting what you were trying to say in the first place. So you have hit the nail precisely on the head.
- DanWeinreb 18y agoI was one of the designers at BEA for four years. (BEA made WebLogic, a leading J2EE server.) Indeed, J2EE requires a lot of annoying boilerplate. Yes, you have to let the IDE handle it for you, which is fine for writing code but not so great for reading (someone else's, or even your own) code. I will assert, though I can't demonstrate it, that had this been done in Lisp, the boilerplate problem could have been substantially alleviated by using Lisp macros. One piece of evidence: J2EE has improved this problem substantially by using Java's relatively-new "annotation" feature, which, broadly speaking, has some of the same mojo as Lisp macros, when used properly. On the other hand, you can do a lot better even in Java. Look at Spring and the other new post-J2EE frameworks. The experience with J2EE has led to learning and improvement in these new "dependency-injection" frameworks, which is definitely a good thing for the Java world.
- stcredzero 18y agoWOuld this be another way of thinking of it: Lisp Macros are boilerplate without the duplication. (And so without the drawbacks)
- Zak 18y agoYes, as long as you keep in mind that macros can be much more than that.