神刀安全网

Using Java 8? Please Avoid Functional Vomit

As the old adage goes, with great power comes great responsibility. The advancements of Java 8 have provided us that power. It’s brilliant! We have true functional syntax in Java which allows us to write beautiful code in a much more terse fashion. We can perform functions in a parallel fashion using streams. We Java developers have finally entered the 21st century.

The thing is, most developers suck. Obviously this is a heavily loaded statement, and fundamentally what I think is good code is different to what you think good code is, but I think everyone can acknowledge there is a significant portion of the developer community in any language (but particularly Java) that just doesn’t know how to write good code. The introduction of the functional programming paradigm into Java 8 is in many cases like giving a Ferrari to someone who’s only just gotten their training wheels off (more cheesy analogies to follow).

I can’t even claim to be the first person to have had this fear. If you wanted to perform functional programming pre-Java 8 the only real option was Google Guava, a wonderful library that did it’s best to make up for some of Java’s greatest shortfalls via the medium of functional programming.

On the Guava wiki they have this beautiful line which has always stuck with me:

Excessive use of Guava’s functional programming idioms can lead to verbose, confusing, unreadable and inefficient code. .. when you go to preposterous lengths to make your code “a one-line”, the Guava team weeps.

In my experience and much to my chagrin, few people headed this advice. This is great advice and absolutely applies to Java 8. One of the greatest features of Java 8 is that it can reduce the verbosity; anonymous functions are a great example of this (taken from my video course ).

return findBy(new Predicate() {             public boolean matches(Movie movie) {                 return movie.title().toUpperCase().contains(partialTitle.toUpperCase());             }         });          …becomes…      return findBy(movie ->   movie.title().toUpperCase().contains(partialTitle.toUpperCase()));

That’s great. The code is now clearer and easier to understand. What a lot of developers don’t seem to understand is that the goal of functional programming is not just to reduce verbosity. Verbosity is not the problem.

Yes, it takes more physical characters in Java than in other languages to achieve things. But honestly, it doesn’t matter. We have great IDE’s like IntelliJ (and sure, Eclipse, but IntelliJ is better. I won’t even mention Netbeans) which do all the hard work for you. I can go just as fast in Java with my IDE as you can in any other language.

Which is why I’m going to say something controversial and against the grain and is going to make everyone angry in the comments. Java’s verbosity is, in most cases, a good thing.

Our goal when programming is not to produce the least amount of code possible, but to produce performant systems that are easy to maintain. An easy to maintain system makes it painfully obvious what all the code does. This can, and often does, mean intentionally writing extra code to make it really really clear what’s going on.

//original, less clear code if(barrier.value() > LIMIT && barrier.value() > 0){ //extracted out to helper function. More code, more clear if(barrierHasPositiveLimitBreach()){

Oh no! Extra code in an extracted method! But it’s a lot easier for the person reading the code to understand what’s going on, and it’s much less likely they’re going to destroy the code by misunderstanding what it’s doing.

Extra code is not the enemy

By this virtue, do not use functional program as some brilliant way to turn all your code into one-liners that are impossible to understand. If that’s your jam, try something like JS1K or one use Perl. Everyone else hates your code.

Let’s take this example from “ 10 Java one-liners to impress your friends ”.  on how to print the song Happy Birthday.

range(1, 5).boxed().map(i -> { out.print("Happy Birthday "); if (i == 3) return "dear NAME"; else return "to You"; }).forEach(out::println);

For me, this code would be much, much easier in the Java 7 style:

for(int i = 1; i <=5; i++){ System.out.println("Happy Birthday " + (i == 3 ? "dear NAME" : "to you")); }

Write beautiful code. Write easy-to-understand code. Do not make me and your co-workers weep. Use Java 8 functionality and one-liners for good, not just to save characters. Characters are cheap.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Using Java 8? Please Avoid Functional Vomit

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址