The relative verbosity of programming languages isn’t the interesting thing; nor is typing doctrine. What’s interesting is the culture of frameworks and what different communities deem valuable. My sense of it is that on Java, too many web frameworks – think JSF, or Struts 1.x – consider the Web something you work around using software patterns. The goal is get off the web, and back into middleware. Whereas a framework like Django or Rails is purpose-built for the Web; integrating with the internal enterprise is a non-goal. —Design for the Web
Java is a general purpose, object oriented programming language. It’s roots in early 90’s object oriented theory, more importantly, the desires and goals of that theory can’t be overlooked when asking why Java is the way it is. The culture of Java design is to push out commitment to a given way of doing things (an “implementation”) as much as possible. In Java culture, dependencies, esp. conceptual ones, are nasty and to be avoided. They’re taboo, even.
The VM
The virtual machine architecture it, itself, the first embodiment of this: rather than benefit from direct access to the underlying operating system and executables there, all access to the OS is mediated via the VM and libraries. It’s considered bad form to actually have to know what OS or even machines you’re running on. There’s good reason for all this, of course, in that you magically swap out the OS or setup and not have to re-code things.
QA loves it when you do that!
Libraries
Nothing represents Java’s distaste for implementation dependency more than the older libraries in Java that follow a plugin architecture. Take JAAS or JNDI, for example. The general functions are abstracted into a handful of classes and interfaces that don’t actually do anything: they just model the possibilities. With some weird wiring up of implementations, you can actually interact with LDAP servers and get things done. The same applies to, for example, XML parsers, transaction engines, and all matter of places.
And thanks to all those layers of abstractions, if you want to magically swap out your LDAP servers to something new (OpenID?), you can just do it!
Again, QA loves it when you do that. They embrace it!
UIs, including the Web
Java’s take on UIs is much the same. You never know when you’re going to want to swap out your UI, so you better work with an abstract layer to buffer you from dependency on any given UI. That Swing based app needs a web UI? No problem, just edit that XML file. Magic!
QA especially likes it when you change the UI.
Sarcasm Check: All this Swapping Out
Now, I’m being glib about all this swapping in and out of things. There are some things that it works well for in Java — file systems, sorting algorithms, collections, and all sorts “low level” API things. At the framework and application layer, however, I think the notion that abstraction help you is largely crap:
- By the time you’ve written your abstraction layer, you’ve essentially written your own framework. Chances are, you’re not a good framework writer, and it’s going to suck, and you’re going to realize that one or two versions down the road and re-write it.
- New frameworks and ways of building applications will come along that you want to use (web applications, clustering, Ajax, mobile access) that don’t readily map to the metaphors, idioms, and expectations of your abstraction layer. At this point, you’ll get upward leak as the new things you want to do are bolted onto your abstraction layer.
- The chief reason it’s crap, and to Bill’s point, is that you’ll always be sacrificing fully taking advantage of things you’ve abstracted away, or making them harder.
To be fair, I’m jaundiced when it comes to heavy abstraction, ladened with the unreasonable exception that most everything will be re-written sooner rather than later. This is probably due to me having worked in less than ideal conditions in the past, so for those of you working in what would be to my experience, relative nirvana: hats off!
If anything, I would concede that abstraction is better left as the coda to a round of development. Again, if you’re smart enough to do design up-front: hats off, dear reader! Your ‘umble servant is not so.
Java Applications vs. Web Applications
More pertinent to Bill’s point of ETags in Java, the problem is that Java developers are building Java applications, not web applications. As such, your concern is doing things the Java Way, not the web way. You trust that by doing things in the Java way, Java will help you avoid the long term problem of maintenance and changeability. The strict practices of Java won’t let your code cement and take ages to update and will prevent your code from becoming incomprehensible piles of tangled wire.
(I could go off on a long tangent about that being the last, and often over-looked, point of good software development, but I’ll keep it short: making it so that, come version 5 of your software, you can easily add in new features with out taking a long time and costing a lost of money. Unless you end up staying at the same programming job for more than 2-3 years, this point is really irrelevant, so most people could give a damn.)
It seems to me that people building LAMP, Ruby, django, or other applications think of themselves more as building web applications with whatever technology tools they need to use: web services, cron
jobs, MySQL, ruby, PHP, python, maybe some Java: whatever. What matters is getting the web application working.
People who using Java see themselves primarily as building Java applications that happen to have a “view” (as we OO head-jobs would call it) that’s the web. Our primary goal is the metaphysical and headless application, not the delivery mechanism. Hopefully you can get a sense for my view of Java culture at this point: it’s more concerned with keeping the concepts, work-flows, and design of the application pure and tidy than optimizing the delivery mechanism, or implementation. Them UML diagrams should look good.
Again, Java’s belief is that this will save you in the long run, which may be true. I have not coded in Eclipse, but those who do, like Mik Kersten, tell me that Eclipse’s object oriented nature over the long haul has paid off when it comes to adding in seemingly “simple” features like hyperlinking to any piece of text in the UI.
Ultimately, Java is a culture that emphasizes knowing less rather than more. Anything you know and act on in your application is a dependency that can cost you time and money in the future. Better, the thinking goes, to deliver less and be able to sustain it over the long-haul than to deliver more and run out of code energy in long run.
People Are the Ultimate Leaky Abstraction
Obviously, all of this is a generalization. But, I think it’s handy for sorting out the difference between Java programming and web application programming. The allegiances for each are to different philosophies driven by the goals of the developers (to stereo-type: long term maintainability vs. ultimate end-user experience), and the resulting cultures and, thus, applications, are starkly different.
The people you choose and the resulting technology they choose will result in wildly different applications than another set of people. That, dear readers, is the ultimate leaky abstraction.
Disclaimer: Eclipse is a client, as are MySQL and Sun.
Technorati Tags: django, lamp, eclipse, oo, leakyabstractions
I agree with you that Java applications and web applications tend to be built from different perspectives. In my experience, most Java applications tend to be for larger projects that have larger development teams and long lifespans where readability, flexibility, and maintainability are the priority.
Web applications, like those built in Ruby On Rails or Django tend to have total development time as their main priority. They tend to be developed by a very small development team that is trying to get something out quickly. Shipping the software is the priority, not long term maintainability.
Both technologies have their place, it just depends on what are the priorities for your development effort.
Hi Rob, I totally disagree with your characterization of Rails being less readable, flexible, or manageable than Java web applications. I think the opposite is true. Rails places alot of emphasis on readability, flexibility, and maintainability. Just because Rails development is typically faster than the equivalent Java development, and Rails advocates are vocal about said advantage, doesn't mean that your typical Rails application is obtuse, rigid, and a support nightmare. From my vantage point Rails has the advantage on all four aspects.
I assume the same for the Django framework as well, but I don't have any first hand knowledge there.
I have built both Rails and Java applications. For scripting, I love using Ruby (I just built a great SOAP web service using soap4r, super easy). For any type of prototyping, I would tend to do it in Ruby On Rails. But when I am building apps for my company where 10+ people will wind up contributing code and where that project will eventually go into maintenance mode, only worked on occasionally, and possibly not maintained by the same person who wrote the initial code, there are a lot of advantages for having the explicitness of Java.
For example, the dynamic nature of ActiveRecord is great for development when you are tweaking the data model while building the view and application layer. But it can be a pain in the ass if you are not familiar with the data model or you have multiple code branches that have slightly different data models. This can happen if you have to support multiple versions of a product.
I'm not a Java fan boy, much of my code at home is in Ruby while most of my code at work is in Java, but I think there is a place for both languages.
If you are building abstraction for the sake of abstraction, I agree that you're giving you more work to do without nothing in return. I've seen people modelling things as State Machines in situation where it was clearly not needed, and where a simple switch statement would suffice and would be clearer.
But on the other side, I think that having an abstracted way to look at the resources you need is a good thing. For example, once you grok how to work with JMS using one implementation like JBossMQ, you'll be able tomorrow to work with JMS in BEA only by learning how to configure it in your next application. It's true that we don't usually go changing the RDBMS, application server and other things in our applications once we go live. It happens, but I agree that it's not all that commom. But we, as developers, go from concrete implementation to concrete implementation as we work on different projects, and thus, we, the developers, benefit from the abstractions in java and JEE, as they help us to have to learn LESS things.
Sure, some people will go and build an abstraction layer right away on their application, making things more complicated from the start, instead of starting small, and putting abstraction only when it's needed. Coming back to my former example: you may have a situation where you have multiple states, but until you are having a hard time modelling the transitions, you can go without an state machine, and doing simple conditionals, If and when this starts to become troublesome to mantain, you go and refactor it using State Machine, but do it when you really need, not because you think you will need it.
Rob: "In my experience, most Java applications tend to be for larger projects that have larger development teams and long lifespans where readability, flexibility, and maintainability are the priority."
Mine too. And in my experience the ilitiies don't work out well. I've no basis to think that web applications written in Java are more maintainable than say PHP, Python, Ruby or ASP. All the serious re-enegineering of web applications I've had to do has been on Java based frameworks, but I don't think this has much to do with the Java language to be frank. The most complex non-Java framework I've used is Zope2. Generally, I suspect trying to split languages on relative maintainability is a red herring.
Remember – this started out around web development, so my response is limited to that.
Mike: "I assume the same for the Django framework as well, but I don’t have any first hand knowledge there"
I suspect that Django is the best web framework, ever written, in any language. Or at least it is for me.
It does a number of things fundamentally well:
– it does not follow MVC. MVC is for desktop apps not web sites.
– it maps URLs to views properly and in a way that's easy to maintain and understand. Understanding the URL space in legacy apps is a huge problem with some frameworks.
– it inverts flow of control for templates, allowing DRY for both includes and skins (you usually get one. but not both). Django templates are its best kept secret and will be come to be ported everywhere.
– it provides the right level of computational power for presentation logic.
– it hides its meta-model from day to day development.
– it's web architecture friendly.
– it provides a battery of utiliities for the things you actually need to do to create sites (such as pagination).
– it does not have a community carrying a lot of attitude, zealotry or defensiveness.
You article finally motivated to start blogging!
The Java culture combined with the marketing and selling machine of JEE and before that J2EE App Servers has done a disservice to the OO ways of thinking. The language syntax and the silly J2EE core patterns have only promoted a cut&paste culture for code monkeys running wild in an enterprisey world. Now the whole charade of container selling is no more. The selling begins of another mega stack of SOA + ESB stuff, for what? to build that get data from disparate sources. Wow, do you really need that many consultants and machines to do that? The Java framework worshipers seem to think so.
"People who using Java see themselves primarily as building Java applications that happen to have a “view” (as we OO head-jobs would call it) that’s the web."
The problem is that if you target the web, your app should really use URIs and HTTP as the *controller* too, otherwise you'll be more prompt to having problems with HTTP caches, users using the "previous" and "next" buttons of their browsers, users willing to bookmark a page, etc.
That's my main grief towards Alfresco, for example. It's a great app, but the "client application" is crappy, because it's a "Java application" more than a "web application".
Hi,
My main difficulty with Java is that it doesn't trust programmers. It starts with the assumption that certain concepts and ideas are safe and useful and others are dangerous. In the early nineties the world did look that way, big nouns was all the rage and calling yourself an architect was an acceptable thing to do :^).
Today we've wised up, and realised that programming just isn't that simple. In the Java world, we find ourselves wishing that we hadn't banished all those other concepts other programming languages still enjoy. Even the OO in Java is in a straight jacket.
I think Java suffered from the idea that we knew it already. The lesson to learn is that we don't and it makes sense to keep your options open while we find out.
Paul.
Great post Cote. This post is not so much about Java the language, but about Java the community and the Java philosophy/mindset. I wholeheartedly agree with Cote's point, it's something that I have felt as well, and I think he articulated it well.
Java gurus tend to get interface-happy: look at the Springframework and Eclipse sourcecode for instance: where almost every class has a corresponding interface. Do all those classes really need several different implementations? I doubt it.
They also tend to get subproject-happy: applications must have layers and these layers must be clearly separated; The "presentation layer" must not touch "data objects" directly, we need "domain models"; or, Let's have a subproject for each layer of the application to reduce coupling, parts of it can also be reused in other projects. Does the reuse really happen down the road? I won't say never, but I think rarely.
In general terms, the Java Philosophy is this: keep modules isolated, so that they can be resistant to change. Because you never know when you are going to need to swap out your UI layer, business layer, data access layer, or your persistence engine, or your database, or your JMS provider, or your J2EE container, or your OS, etc, etc.
I am not dissing this philosophy, it is very useful to be able to swap out some of these components, but others, not so much. There's a balance somewhere. I think that in a lot of cases simply refactoring code is enough to cope with change. It really isn't hard if you keep your code DRY, and have good test coverage. Java folks in general are just too in love with the idea that their finished code should work with every imaginable situation that can arise.
??… ????? ????????? ???? ??? ???? ????? ?????????.
????????? ????? ?????, ? ?? ???????? ?? ?? ???????
??????? ??? ?? ????, ????? ???????? ??????, ??? ????? ????????
?????????? ????- ??? ?????