Fair amount of sensible things have already been said - I agree with a lot of it.
I prefer well-named and small (private) functions/methods over comments. Comments are fine for documenting your public APIs, as well as some implementation details, quirks and hacky workarounds - but other than that, I prefer to split into small and well-defined steps, and let the code speak for itself. If you end up with method names that are long or weird, that's often a good indication of a code smell.
However, what one person might find "clever" is what another finds "
DRYw". I don't advocate using esoteric language features just for the heck of it, but I'm also not a fan of avoiding anything-but-the-basics because you need to cater to throwaway unskilled outsourced programmers. I routinely use the
ternary operatorw, as I find it can make code easier to read (yes, sometimes even with
nested ternaries!). It isn't suitable in every situation, and bad use can make code unreadable. I often use it when declaring
final variables conditionally, when the logic isn't bad enough to warrant factoring out to it's own method.
Use of the ternary operator doesn't mean I'm in the "as few lines of code as possible" camp, though. I often break condition of if-statements into (properly named) booleans or method calls, which obviously results in more code lines... but also in better readability.
As an example of what some people might find "clever", here's a small snippet of code for dealing with
JCRw nodes. It's a somewhat low abstraction to be operating at, but sometimes it's the right tool for the job - but there's so much red tape and overhead to deal with, when all you really want is "possibly the value at some subnodes property, or a default value if subnode or property doesn't exist or something goes wrong." - Java doesn't have Lambdas, but it does have the (much clunkier, syntax-wise)
anonymous inner classes.
Without further ado:
public class NodeHelper {
public static final Logger log = LoggerFactory.getLogger(NodeHelper.class);
// ...other overloads omitted
/**
* Returns a property (or, on error, a default value) from a subnode of a given node.
* @param node root node
* @param path "path/to/subnode@property"
* @param defValue default value
* @return given property of subnode, or default value
*/
return safeGetPropertyInternal(node, path, defValue, new Transformer<Calendar>() {
return prop.getDate();
}
});
}
private interface Transformer
<T
> { public T transform
(Property prop
) throws Exception; }; private static <T
> T safeGetPropertyInternal
(Node node,
String path, T defValue, Transformer
<T
> transformer
) {
try {
final String[] pathAndProperty
= path.
split("@"); final String subPath
= pathAndProperty
[0]; final String property
= pathAndProperty
[1];
if(node.hasNode(subPath)) {
final Node subNode = node.getNode(subPath);
if(subNode.hasProperty(property)) {
return transformer.transform(subNode.getProperty(property));
}
}
}
log.error("safeGetPropertyInternal: exception, returning default value", ex);
}
return defValue;
}
}
It's pretty quick-and-dirty code, but it works well enough for production (*knock on wood*). There's still a lot of Java red tape, Scala or C# (or even C++11) lambdas would have made the various safeGetProperty() into oneliners. Still, no superfluous exception handling all over the place, a fair armount of code lines saved (but most importantly, the core logic is centralized - one place to bugfix). And the "cleverness" is hidden as an implementation detail behind a simple-to-use public API.