Tuesday, February 05, 2008

Reflection

Work has been interesting the last couple days, as I have spending about half my time learning about Java's reflection capabilities. I have nearly succeeded in completely generalizing the action code for our Struts app here at work, which to me is a victory. For one, it removes the need to ever write/generate it again on new tables. More importantly, it allows us to fix something in one place in the future, instead of once for each table. I say nearly succeeded because I have one minor issue to address, and really a couple things I'd like to find a cleaner way to do.

Word on the street is that Java reflection is slow, etc. But who cares? If this site was going to be used by millions, it might be an issue, but it's not, and we aren't doing any computation with it, just presenting and storing information. I find the task more meaningful because it solves the more general problem.

I think there are really two styles of coding. One of them solves the immediate problem at hand via the direct approach. I use this all the time when writing some script to parse/scrape text or some other task. You build something specific that solves the problem and get it done. The second style doesn't really come about until you find yourself repeating something using the first style.

The first time I wrote a script in ruby to scrape a website, I just used the built in HTTP library, loaded the page, searched it with a regex and spit out my results. Simple, quick, and it worked. However, about the third time I found myself scraping a page, I realized that I was duplicating a lot of code and really wanted a cleaner more general way. Now if I had been a trailblazer, I would have sat down and written a library to parse html with css selector or xpath support and then used it in my scripts. Thankfully, the people who made Hpricot did this for me.

Using the same code in multiple places just seems like a bad thing. This isn't really an earth shattering idea... it's called abstraction and has been the name of the programming game since the beginning 60 years ago. My point is that I find the enjoyable part of what I do is abstracting. Once you have done the straightforward solution, it is no longer challenging. I have done enough websites to be bored with the straightforward task of putting up forms, capturing input, and saving it. The fun for me writing the abstract system to do it all for me. That was why I wrote that generator to begin with. At the time I was cheating by using my knowledge of Ruby to metaprogram in Java. Now I have learned about how Java does it's own metaprogramming, so I'm trying to make my generator (mostly) obsolete too. At some level I can't entirely do it with Java reflection (building the table objects with reflection would just be too slow as far as I can tell), but I have faith that I can still get rid of a few more things. The xsl file will remain, and the DAO and entity objects, and the hibernate mappings, but I think I still have some low hanging fruit to attack.

Completely unrelated to all this, I have several exciting ideas I'd like to work on, but I'm trying to keep my focus on the project at work. I have problems working on two things at once (or on the same day anyway), and I'd like to leave a good impression here. At least I can tinker on the weekends.

1 comments:

Allan said...

We're like halfway done with NetJ 2.0

Actually...not NetJ. We should abstract that out too. It should be a webapp for displaying/editing records for any database system. We just have to provide a way to easily customize how the information is displayed. And a way to add in additional computations if something is more complicated than simply saving the input data to the database.