As a Scala developer I'm obviously biased, but I would add "try out scala" to this list.
Why? Because learning new programming paradigms is beneficial whether you stick with them or not. And Scala is easier for a Java developer to start with than Lisp or Haskell or Z or anything so foreign.
It is simple to get into because you can start basically like "java without semicolons", and IntelliJ community edition has excellent Scala support.
2013 Scala newbie here. Scala feels nice in the way that Python feels nice. They both give the newcomer some say in what programming paradigm they get to think in. I like languages like that.
I'm a little hesitant to call Scala "Java without the semicolons". Going too implicit too soon might cause things to go horribly wrong while climbing the learning curve. Besides that, it might scare my colleagues if I was ever to bring that kind of code to work.
Looks like Spring/Hibernate is losing it's shiny new gloss. I wonder what the next round of 'hammer to fit all nails' that 'we need to rewrite everything in!'
Writing code using annotations?
Dynamic languages on top of the JVM like Scala? ;)
This year ,I will recover from my Spring addiction. The grim realization that Spring ruining me a as a programmer dawned upon me when I looked at my project that was using Spring Integration and I could not figure out what the heck was happening . There was so much xml that my eyes bled ! Other Spring addicts suggested using the Spring IDE for visualizing Spring Integration xml, but I think the Spring way of life just makes simple things complicated. I have decided to refactor all my Spring Integration code and instead use Clojure ( perhaps in most non-idiomatic fashion) to glue java static methods into a sequence of functions that provide the same workflow as Spring Integration. If this works out, I will target Hibernate next; I hate having to do master hibernate/ORM api to do SQL operations.
>Stop worrying about the procedural code [...] I don’t see a lot of value coming out of the abstractions we create.
I completely agree here. If you're not getting value out of the abstractions, don't introduce them.
However, abstractions in general and OO design does solve many issues that arose from procedural programming. The trick is to recognize the problems, and focus your design around those.
Good luck with that ! You are not using SOAP because two programmers decided it was the best integration solution for distributed computing . We, you and I, are using SOAP because our CIO /Sr. VP was invited to an offsite retreat or management executive seminar where over a course of the finest hooch and blow, an enterprise vendor ( most likely IBM or Oracle) convinced your exec that having SOAP is like having an insurance against personal accountability for project disasters; after all nobody has ever got fired for buying IBM. So rail and rant against SOAP at your own peril.
In my last project, I was asked to send a file, that was uploaded by users onto our servers, as a SOAP message over TIBCO where another application read the SOAP message and put the file into a folder where it was processed by a nightly batch job. On the plus side , the managers and executives responsible for the design were all well connected charming people with PMP certification.
Learn YAGNI. Tattoo it on your friggen foreheads. Run lean... No, you DONT need to build a framework to complete your project!
Stop abstracting god dang everything. Interfaces and composition are GOOD, use them. Inheritance and generalization use SPARINGLY, or not at all! Before you create an abstraction, are you CERTAIN sometime in the future you will swap the impl out or are you more likely to throw away the code? Think about that.
Instead of Spring, consider CDI on TomEE. Dependency injection is GOOD, but you don't need to friggen inject everything in the mothafriggen world. Since CDI has a smaller feature set than Spring, you will be forced to not be as stupid. -Said a recovering spring-a-holic
Here's a slight disagreement with the article:
JPA is fine, but Hibernate is bad, slow, and it's made by Gavin King, the man who has a terminal case of 'wasn't invented here' syndrom. Use EclipseLink and stick JPA2, and pull in Redis/Mongo where appropriate.
Avoid EE6's version of CDI (WELD/OWB) and EE6 all together. Its slow and causes more problems than its worth. If you really want CDI, use gluice.
Guava is your friend.
Avoid JPA, specifically the parts regarding session management. Never liked it myself and Ebean[1] is a far cleaner ORM which reuses the JPA annotations for mapping classes.
Writing a user facing website? I don't have a good answer here honestly. JSF/EE6 is terrible, GWT - yuck, Wicket - yuck, in my opinion they all suck. For related options Grails seems ok, Play! seems ok, Rails on JRuby seems ok but I haven't used any of them enough to have any real opinion of them. We're currently using angular.js and Jersey for the API on the backend.
Groovy 2 is pretty awesome when performance isn't critical, use it.
Yes, Joda-Time is awesome and a default include is pretty much all of my POMs. I'd also add that if your dealing with monetary fields / calculations, Joda-Money is also a great way to avoid common pitfalls.
Yah I should have mentioned Guice, I just did my first project with it. It still enables a boat load of stupidity, but at least it doesn't have the cruft that comes with EE6.
Java is a language for people good at resisting temptation. It gives you all sorts of ways to make your code look nicer, more elegant, but the only way to be productive in Java is to avoid all of them.
In my experience, you can be more productive in Java than in any other language, because it has by the best tools and libraries. However, don't use reflection, don't use cloning, avoid automatic (de)serialization, don't doc needlessly, don't separate interface and implementation when you don't have to, use refactoring and code generation, don't feel bad about code duplication.
Most of all, always consider that coding is cheap. Changing a constant? Easy, not hard. Changing interfaces? Easy, not hard. Introducing an alternative implementation? Easy, not hard. Changing names? Easy, not hard. Adding new types? Easy, not hard. You don't need to think about easy things in advance, think about the problem instead.
I'd expect languages that require far less code for pretty much anything, and have far more compile-time safety to be more productive both at the prototyping stage, and at long term software maintenance.
I disagree with "Stop using Anonymous Inner classes and just bite the bullet and wait for 8." Are you going to stop development while you wait for 8 too?
Most IDEs tend to hide a little of the noise associated with anonymous inner classes and, at least, with IntelliJ, the auto-completion for things like Guava's Function are huge time savers that make it much more bearable.
Now, should you think twice before you reach for an anonymous inner class? Of course! But there are many situations in which "closures"/"functional-style" anonymous inner classes can significantly decrease the amount of code written and/or make it much clearer. Basically, it lets you stay D.R.Y. much better.
One very common situation is reusing a complicated data structure traversal, just to be able to do two different things with the same inner pieces of data. Without the ability to "pass in code" using anonymous inner classes, the way to avoid code duplication is to accumulate the final destination items in a list and return that from the traversal code, such that this intermediate list can then be fed into the two different code paths. Of course, often such a refactoring is not easy or litters the otherwise-clean traversal code with the details of the intermediate list population. If the intermediate list gets too long to fit into memory or if pagination is required, then you end up having to return an iterator of lists, etc. It just gets messy.
Contrast that with code that takes in an anonymous inner function to apply to each piece of data. Bam, it's so much simpler. Want to start paginating the traversal? No problem, the calling code is none the wiser.
Developers who've been using closures are very familiar with this style of coding. The ugly syntax of anonymous inner functions raises the bar for using them above many simpler situations, but the greater utility cannot be disputed.
17 comments
[ 20.7 ms ] story [ 49.3 ms ] threadWhy? Because learning new programming paradigms is beneficial whether you stick with them or not. And Scala is easier for a Java developer to start with than Lisp or Haskell or Z or anything so foreign.
It is simple to get into because you can start basically like "java without semicolons", and IntelliJ community edition has excellent Scala support.
I'm a little hesitant to call Scala "Java without the semicolons". Going too implicit too soon might cause things to go horribly wrong while climbing the learning curve. Besides that, it might scare my colleagues if I was ever to bring that kind of code to work.
Writing code using annotations? Dynamic languages on top of the JVM like Scala? ;)
I completely agree here. If you're not getting value out of the abstractions, don't introduce them.
However, abstractions in general and OO design does solve many issues that arose from procedural programming. The trick is to recognize the problems, and focus your design around those.
In my last project, I was asked to send a file, that was uploaded by users onto our servers, as a SOAP message over TIBCO where another application read the SOAP message and put the file into a folder where it was processed by a nightly batch job. On the plus side , the managers and executives responsible for the design were all well connected charming people with PMP certification.
Learn YAGNI. Tattoo it on your friggen foreheads. Run lean... No, you DONT need to build a framework to complete your project!
Stop abstracting god dang everything. Interfaces and composition are GOOD, use them. Inheritance and generalization use SPARINGLY, or not at all! Before you create an abstraction, are you CERTAIN sometime in the future you will swap the impl out or are you more likely to throw away the code? Think about that.
Instead of Spring, consider CDI on TomEE. Dependency injection is GOOD, but you don't need to friggen inject everything in the mothafriggen world. Since CDI has a smaller feature set than Spring, you will be forced to not be as stupid. -Said a recovering spring-a-holic
Here's a slight disagreement with the article:
JPA is fine, but Hibernate is bad, slow, and it's made by Gavin King, the man who has a terminal case of 'wasn't invented here' syndrom. Use EclipseLink and stick JPA2, and pull in Redis/Mongo where appropriate.
Writing a service? Use dropwizard[0]
Avoid EE6's version of CDI (WELD/OWB) and EE6 all together. Its slow and causes more problems than its worth. If you really want CDI, use gluice.
Guava is your friend.
Avoid JPA, specifically the parts regarding session management. Never liked it myself and Ebean[1] is a far cleaner ORM which reuses the JPA annotations for mapping classes.
Writing a user facing website? I don't have a good answer here honestly. JSF/EE6 is terrible, GWT - yuck, Wicket - yuck, in my opinion they all suck. For related options Grails seems ok, Play! seems ok, Rails on JRuby seems ok but I haven't used any of them enough to have any real opinion of them. We're currently using angular.js and Jersey for the API on the backend.
Groovy 2 is pretty awesome when performance isn't critical, use it.
[0] http://dropwizard.codahale.com/
[1] http://www.avaje.org/
In my experience, you can be more productive in Java than in any other language, because it has by the best tools and libraries. However, don't use reflection, don't use cloning, avoid automatic (de)serialization, don't doc needlessly, don't separate interface and implementation when you don't have to, use refactoring and code generation, don't feel bad about code duplication.
Most of all, always consider that coding is cheap. Changing a constant? Easy, not hard. Changing interfaces? Easy, not hard. Introducing an alternative implementation? Easy, not hard. Changing names? Easy, not hard. Adding new types? Easy, not hard. You don't need to think about easy things in advance, think about the problem instead.
That's quite a bold claim...
I'd expect languages that require far less code for pretty much anything, and have far more compile-time safety to be more productive both at the prototyping stage, and at long term software maintenance.
It wasn't a broad claim, it was an observation.
Most IDEs tend to hide a little of the noise associated with anonymous inner classes and, at least, with IntelliJ, the auto-completion for things like Guava's Function are huge time savers that make it much more bearable.
Now, should you think twice before you reach for an anonymous inner class? Of course! But there are many situations in which "closures"/"functional-style" anonymous inner classes can significantly decrease the amount of code written and/or make it much clearer. Basically, it lets you stay D.R.Y. much better.
One very common situation is reusing a complicated data structure traversal, just to be able to do two different things with the same inner pieces of data. Without the ability to "pass in code" using anonymous inner classes, the way to avoid code duplication is to accumulate the final destination items in a list and return that from the traversal code, such that this intermediate list can then be fed into the two different code paths. Of course, often such a refactoring is not easy or litters the otherwise-clean traversal code with the details of the intermediate list population. If the intermediate list gets too long to fit into memory or if pagination is required, then you end up having to return an iterator of lists, etc. It just gets messy.
Contrast that with code that takes in an anonymous inner function to apply to each piece of data. Bam, it's so much simpler. Want to start paginating the traversal? No problem, the calling code is none the wiser.
Developers who've been using closures are very familiar with this style of coding. The ugly syntax of anonymous inner functions raises the bar for using them above many simpler situations, but the greater utility cannot be disputed.