Monday, September 10, 2012

Capital Punishment - Countries and Capitals

Capital Punishment - Countries and Capitals

Using the knowledge I'd gained in the tutorials I mentioned last post, I created the above web application and got it hosted on Heroku.

By my estimates, this project took about 16 hours of actual work plus about 4 hours of tutorial work. 20 hours to create, polish, and publish a web application doesn't seem bad to me.

The tutorial that I originally used was great, but it was for a very simple application and didn't scope quite as well as I had hoped. When I made Capital Punishment, everything worked well for me when I ran the app from my local machine. Then I pushed it to Heroku and everything changed.

The initial page would load, which made me fairly happy. It was clicking things and performing actions that began to disappoint me. Whenever I would navigate to a different page, Heroku would give me an Internal Server Error. So I checked my logs to see what was going on:

NameError - uninitialized class variable @@question_statement in BasicObject: heroku

To be honest, I should have seen this coming.  I had created a large app with very little Object-Oriented design put into it. What was happening was the context-switching caused by performing POST actions was losing track of my class variables. But "It Worked On My Machine." Why? I'm not entirely sure, but I think it has something to do with the way Heroku loads the pages.


So how did I fix this? Massive refactoring (my favorite kind of refactoring). I created a base class with all the shared logic, and then created two Singleton classes for the two game types: CountriesAndCapitals and StatesAndCapitals. I then referenced these singleton instances from the HTML and from my POST methods, and the problem was fixed.

Refactoring my code to be more OO provided an incredible amount of optimization of my original code. Now, the data for each game type is only being loaded once and the US data won't be loaded at all unless you start playing the US game. All of the repetitive code I wrote to load the two entities was modified to be in the base class. Everything that was painful to change because it was buried inside poorly-named methods became easy to refactor.

In this case, I was suffering from a combination of laziness and over-enthusiasm. I really wanted to get that code done before the weekend was over, and so I just threw a bunch of non-OO text at Netbeans until it worked.

I think I've learned a lesson from this: Write good code. It doesn't matter if you're in a hurry, or following some tutorial using sub-par styles; you should always try to write the best code first.

No comments:

Post a Comment