Wild Man's Shore

Tuesday, January 17, 2006

TurboGears vs Java

I have a large, upcoming project looming at work; no details can be revealed at present for confidentiality reasons, but it will be fairly high-traffic, and it will have a lot of features.

As a TurboGears contributor I immediately thought of using this platform for the task: it has everything the project will need, for example localization (must support English and Finnish), identity management, etc. However, it is still unstable (coming up to version 0.9) and in the interests of the customer I felt I should investigate other possibilities first.

I did some Java programming a couple of years ago, mainly non-web/Swing stuff but also some servlet work with Velocity and plain JDBC. One of the requirements is that the application may have to integrate with a third party tool which happens to have a Java API, so Java may be a fine contender.

Looking at the Java landscape today after years of PHP/Python it's quite clear that J2EE, in the sense of web tier + EJB, is hardly in use any more except perhaps in the largest of companies. The most popular solution (going by blog posts and discussion groups, I have no idea about real world usage) seems to be Spring + Hibernate. Digging deeper I followed an excellent Spring tutorial to get started.

Spring has an ambitious scope, but the part I was looking at, Spring MVC, is fairly straightforward: it uses the Command pattern, each command class represents an "action" such as login, checkout, do search etc. Hibernate is again a pretty straightforward way to map relational models Java objects. Spring can be used with JSP, Velocity, Tapestry or some other presentation layer.

Localization is well supported in Java, and I liked how it was taken as granted that you need localized messages, unlike in PHP or Python where (despite huge numbers of non-Anglophone developers) it seems more of an afterthought. Certainly that is the impression I got when I wrote the i18n package for TurboGears. For example, handling Unicode in Python is a real pain. GNU gettext is supported by Python but somehow the Java localization system seems a lot simpler.

One thing that came to mind however was the sheer verbosity of Java. I had forgotten just how much line noise is required to even do the simple stuff. I don't mean the core syntax as such but the tendency of Java developers to fly into a stratosphere of abstraction layers. Along with the countless number of XML files I can see why Java developers love (or need) their IDEs so much; even for a simple tutorial application the mind-boggling number of abstract classes, interfaces, XML configuration files and so on and so forth left me wondering how a single person could possibly keep track.

Nevertheless, Ant was nice once it was up and running; compiling and deploying to Tomcat and restarting Tomcat could be done with a single command. A little more work there than,say, reloading a PHP-generated page in your browser, but not oppressive. And catching compile-time errors was a time-saver.

That's the good thing about Java vs. Python or Ruby; its boring predictability. But why the love of abstraction ? In TurboGears, for example, you have a SQLObject class for your model, say Product. It may look something like this:

class Product(SQLObject):
description = StringCol()
price = CurrencyCol()
quantity = IntCol()
category = ForeignKey("Category")

That's it. 5 lines of code and your class is done. You can access it in your code for example like this:

# get all products costing less than 10 euros

cheap_products = model.Product.select(model.Product.q.price < 10.00)

The equivalent Java code may exist not in 5 lines but 5 files, for instance:

  • Product.java : plain Java object to hold data
  • ProductDao.java : interface for accessing Products
  • HibernateProductDaoImpl.java : Hibernate-specific implementation of ProductDao
  • ProductService.java : class which accesses ProductDao interface and returns Product instances
  • Product.hbn.xml : Hibernate XML mapping for Product to relational table

Now granted the added abstraction gives you greater flexibility down the line: if in the future you decide to replace Hibernate with TopLink or some other ORM, or you get your products from XML or flat files or over a web service, you don't need to gut your code across the board, just drop in the new classes, change some XML configurations, and you're done. The equivalent SQLObject code in Python works for a number of relational databases but any more significant changes (e.g. another ORM or entirely different storage layer) would require recoding parts of the app. Of course you could write a Python application with a similar degree of complexity (Zope3, I'm looking at you). But such abstractions in the Python world are uncommon.

In the real world, however, how often are you going to change your storage layer ? For example, if I'm building an online store I design the relational model to a T and go out and set up a database, say Oracle, and design the application to talk to that. That is the part of the system that is least likely to change.

Of course Java developers would accuse me of over-simplification, and they would probably be right. And Java developers earn a whole lot more than Python developers, so maybe they have a point :-)

Next post: comparing TurboGears and Ruby on Rails!


At 10:50 AM, Blogger pbsl said...

you have a nice site. thanks for sharing this site. there are various kinds of ebooks are available here



Post a Comment

<< Home