I really hate when people repeat something they were taught as a "good thing to do" without thinking about it.
This is true for all aspects of life, starting with right to own a gun over various beliefs to being politically correct.
But there are also plenty of examples in programming.
This will be my list of arguments against illogical statements repeated all over the world by people just because some expert said so 20 years ago in totally different context.
Public class fields
class Foo { public String bar; }
This is not evil. Evil is to make it part of an API. But if you use it within your package, or even a class, it's totally OK. Especially if the classes are not public.
Think of C. How did you model structures in it? struct { ... }. A class with public members is Java's structs.
And if you have an internal algorithm which uses structures, it's nonsense to create a full-blown classes with getters and setters.
If you want to have some examples, check the sources of JDK. Almost any imlementation of complex algorithms uses this. E.g. regular expressions.
Sure, we can argue that JDK isn't always the best Java code. But then, what is.
Separating resources and java code
This nonsense came with the fame of Maven. Lazy programmers didn't separate these in Ant, because it was nearly twice as much XML code.
But Maven made it so easy - all the archetypes had it, IDEs support it, etc. Nice.
But then, some projects intentionally do:
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*</include> </includes> <excludes> <exclude>**/*.java</exclude> </excludes> <filtering>false</filtering> </resource> <resource> <directory>resources</directory> <includes> <include>**/*</include> </includes> </resource> </resources>
Then someone comes and says, "you know nothing about resources separation, John Snow".
Well, thanks, Mr. Smart, but you're wrong.
Resources separation is not done just because "it's good, mkay?", but for a purpose, which is:
Different people sometimes work on these two, and they are handled by different processes at different time.
But if you have source file, which just happens not to be compiled, then it totally makes sense to have it right next to java files.
Examples of such can be various built-in scripts, Hibernate XML descriptors, log4j.properties, jaxb.properties, default config files, built-in data, etc.
All the kind which is maintained by the very same people which work on the code around. (Unless these files are supposed to be changed by admins etc).
This is especially true for test suites.
Note: Don't confuse with putting these files to the resulting distributed artefact - that's a different story.
"Prefer composition over inheritance"
Gavin King posted on Google Plus:
Please, please stop saying "prefer composition over inheritance", as if there were no problems best solved using subtyping. And please stop nodding sagely every time you hear someone else say it. Through unthinking repetition, this phase, originally meant as a suggestion to weigh up the advantages and disadvantages of different solutions, has totally lost its original meaning in most people's heads, and has now become a vague, general-purpose item of FUD deployed to make us feel uncomfortable about using one of the basic modeling strategies in our toolbox. There are problems best solved using subtyping (assuming our language has subtypes) and there are problems not best solved using subtyping. But "prefer composition over inheritance" taken literally and without qualification gives us exactly zero advice on how to distinguish the first set of problems from the second. We will only become better programmers when we quit mindlessly repeating vague rules of thumb passed down from the 70's or 80's, and actually start using our own brains to think things through and analyze potential solutions in terms of objective software engineering goals. Grrrr.
Don't use /, use File.separator
Happened to me several times that I posted a classloading code, and someone told me "don't use /, that's platform specific". Well, that's true. But only for filesystem paths. For class paths, it's always /. Someone suggested that even for an XPath expression. No comment.
Exception-driven execution flow
Ignoring exceptions
Sometimes, exceptions _can_ be ignored - e.g. if they are misused in a library for flow control.
Label and break - Java's GOTO
Comparing instances using == vs. equals()
Comparing objects using just Java heap address is enough in many cases - no need to call hashCode() of both objects. This is typically true for objects which are not stored anywhere during their lifespan. (Not sure if JIT compiler optimizes using equals() on objects without overriden hashCode().)
Using JPA Entities through all layers of the app
Mixing user input validation and persistence layer validation
Using CRC32 for hashes
There are SHA1 and MD5. But who needs such a strong hash for just hashing purposes (not security)? What's the chance that you'll find 2 same contents for which CRC32 will give you same hash?
Using eval() in various scripting languages
Scripting languages have the strong advantage in ability to execute code on the fly. That's almost the definition of them.
Sometimes, generating a code is the most effective way to do the job (though not the ellegant). Saying "eval() is evil" blocks you from those solutions.
Using with(...) in JavaScript
Javascript's stack can be a tricky beast, especially with closures. "with( ... )" should be avoided in code where you call various lib's code, but in code which is purely yours, "with()" can shorten your code neatly.
Single return statement in a method
Someday in the ancient ages of C or Pascal programming, someone stated that a method should only have one return point. There's no study for that, it's just the matter of taste. Actually, multiple return points can save you a lot of parentheses. If you don't like returns, don't force your taste on others.
Stored procedures and triggers are evil
Using underscores in Java method and package names
Underscore is not a common character to use in Java code, since it's so "C". But sometimes, it makes sense. Especially for internal methods. For exwemple, it can nicely denote which methods do not check the input.
Overrated call recursion (with recent popularity of functional languages)
Recursion can be done in few ways. With the increasing popularity of functional languages, some people solve recursive problems by recursive method calls.
Why not. But for simple problems, it's a performance issue. It's enough to put information on a stack. Additional method call consumes more data than just the payload.
To be continued...
That's not all, I often people uncritically accepting anything what reaches their ears, the only filter is "how famous the guy who said it is".
So I have a good source :-)
Comments