The most important piece of Unix philosophy for programs is "do one thing and do it well". If only more programs, and more libraries, followed that basic principle, and stopped bloating their code with runaway featuritis. As a real-life example of what to do, and what not to do, I take Proj4 and Geotools.
Proj4 is a C program/library that projects coordinates from one system to another. It doesn't do or include anything else -- i.e. have a gui or receive emails. The one thing that it does though, it does to exhaustion. It handles a laundry list of projections and conversions: indeed, the complete laundry list as far as I can tell (though I'm not expert). And it's easy to use from the command line or as an api.
Geotools, in contrast, is a bloated monster of a Java framework. It handles all things Geo. It can read shapefiles, csv files, gml files, mif and vpf (god knows what those are). It graphs, it visualizes, it projects and converts. And I venture to say it does no one thing particularly well.
I've only used it for projections, so perhaps I'm biased. You might point out that obviously Proj4 is going to be better at projections, cause that's all it does anyway, whereas Geotools has to a bunch of things. I'd argue that the Unix "one thing do it well" is a superior, and more composable, design than the "do it all at once" alternative. I'd rather have a bunch of cohesive and exhaustive libraries that I can compose together to get the functionality I need, than a massive behemoth that I must take or leave.
In all fairness, this post is motivated more by my frustration with Geotools weird plugin architecture than my concerns for their code-base. I spent a considerable amount of time trying to figure out how their crazy service-registry/factory/class-loader contraption worked, and it honestly left me exhausted. They have attempted to make their massive framework modular by (wait for it) dividing their code into modules... but the way they tie it all together is absolutely horrendous. They have a home-baked auto-wiring solution, like what you'd get in Spring (but would never use cause they advise against it and it's bad anyway). If you drop a jar on the classpath that contains an implementation class, their service-registry/factory/class-loader contraption attempts to auto-magically suck it up and make it available. Obviously this only works under the best of circumstances, and requires a deep understanding of the contraptions inner-workings of it is to be debugged or modified at all. There is a reason the Spring framework (and presumably other similiar frameworks) avoid auto-wiring and have configuration files. If for no other reason than a configuration file is more explicit: at least then you know which concrete classes are implementating your interfaces. In this case, I had to step through the initialization process with the debugger to find out what concrete classes I was getting. Ick!
Of course, I'm sure they had some mangled reason to do what they did. It's just frustrating coming in from the outside and not seeing the benefits of this madness, whatever they are--or if they are.
Subscribe to:
Post Comments (Atom)

0 comments:
Post a Comment