You can come up with ugly names for classes in any language.
You can come up with ugly names for classes in any language.
After years of consulting I can't remember how many times I've walked into an Enterprise Java Shop(TM) to find TemporalSystemLoadOrganizers, IntransitPredeterminedApplicationUtilitySources, MetaphysicalManipulatitiveQuantityDisorderRecognizers only to find out that at the end of the day these abstract-factory-driven-decorated-decoupled-dynamically-injected-frameworks tend to do such obscure/complicated things as "Update a user's first name" or "Show the last item the user has purchased"...
Again, not Java's fault and no question you can write very fast, beautiful and clear code in Java. I'm sure every language has specific warts and most of them probably reside more with the community than the syntax.
For example, assume I've got a list of students, and I want to show all the ones who haven't taken at least one exam, sorted by last name. Here's the relevant pseudocode in Rails:
class.students.select {|student| student.tests.inject(false) {|acc, test| acc || (!test.taken? )}}.sort {|a,b| a.last_name <=> b.last_name}
That just flows from my keyboard as a Ruby/Rails programmer, is pretty much instantly comprehensible to other Rails programmers, and (while others might disagree with stylistic choices, variable names, or whether to use that weird &syntax to do the sort) would be considered "good enough Rails code to ship."
I will take the liberty of pasting my Java implementation into a gist -to avoid breaking HN:
https://gist.github.com/3760402
A nice, svelte 38 line method, which will be reused via copy/paste a hundred places in my codebase.
Incidentally, at my previous Big Freaking Enterprise job, the user need "Make a page for a class where we can see all students who haven't..." would get quoted to them as "No problem, that will cost you $1,000. Are we green-lit to implement or do you want docs written first ($250)?", because the core logic I've shown you is the tip of the iceberg of how sucky that experience is going to be. We haven't even started with the XML files and annotations required to hook the new actions together yet. By comparison, as a Rails developer, in lieu of getting you to sign off on a $1,000 line-item to your next invoice I'm inclined to show you a totally working page and ask you "Is this what you wanted?" because implementing it is easier than talking about implementing it.
can be reduced even further using the all? method
!student.tests.all?(&:taken?)
public class Student implements Comparable<Student> {
@NotNull public List<Test> getTests() { ... }
@NotNull public String getLastName() { ... }
@Override public int compareTo(Student that) {
return getLastName().compareTo(that.getLastName());
}
}
List<Student> studentsWhoHaveNotTakenAtLeastOneTest() {
TreeSet<Student> studentsMissingAtLeastOneTest = new TreeSet<Student>();
for(Student student : getStudents()) {
boolean allTestsWereTaken = true;
for(Test test : student.getTests()) {
allTestsWereTaken &= test.isTaken();
}
if (!allTestsWereTaken) {
studentsMissingAtLeastOneTest.add(student);
}
}
return new ArrayList<Student>(studentsMissingAtLeastOneTest);
}
The point I'm (perhaps ineptly) making is not that Java isn't all that verbose (because it obviously is) - rather it's that you don't get much of a stack of abstraction by default. If you don't take the time to implement that abstraction, you're going to have a bad time, but if you do, it's not appalling. def studentsWhoHaveNotTakenAtLeastOneTest = getStudents.filter{s => s.getTests.filter{t => !t.isTaken}.size > 0}.sorted
You could get a similar amount of code in Java using something like FunctionalJava but that's not really a fair comparison, because patio11 is illustrating Java as it's spotted in the wild, and thus so am I. But with appropriate libraries and implementation patterns you can certainly write concise Java if you so choose.Similar to "nobody got fired for buying IBM", the mindset was that "nobody got fired for building layers of abstraction just in case."
It's the culmination of the second system effect.[1] Without a pervasive unit testing culture, the big enterprise answer to "what if" is "let's add a point of flexibility here."
Obviously, people should be held responsible for building unnecessary abstraction layers like that. They waste time and are often wrongly abstracted, so when you do need to go in to refactor, you end up having to fight the pre-existing "what if" abstraction.
And it's not about the language per se. (You can write clean, simple code in Java, but you would have to write it pretty much from scratch.) It's about Java culture, which encourages this kind of stuff.
And yes, I had been a Java programmer for many years. I used to like the language at some point. But several integration projects made me like its culture less and less.
And that's precisely the issue.
It's a part of a third-party open-source library that implements a "dependency injection container". It's a pretty abstract concept to begin with - of course it's going to need to do high-level, head-in-the-clouds-type stuff that on first glance you think you would never need.