Pages

Showing posts with label style. Show all posts
Showing posts with label style. Show all posts

Tuesday, June 19, 2012

why you shouldn't do things in your constructor

Last week I needed a free HTTP server for a project I was working on at my job.

Naturally, most folks would suggest Apache here, but I had the caveat that my server's footprint needed to be very low - no bells or whistles. After adventuring through Google for a while, I finally turned up a cute little free-to-use thing, a single Java .class file called NanoHTTPD. It was an ultra-lightweight HTTP server, built off the core ideas of the HTTPD monster but without all the bulk - where Apache is the big brother, NanoHTTPD is the anemic, weaselly stepchild. Simply compile and run the class file and you have a working web server on your machine. Need more functionality? Easy as cake: just override the "serve()" method, called when the server process an HTTP request. It was perfect.

All was proceeding as planned - I was extending the NanoHTTPD class and overriding "serve()", just as the creators intended - when I came across a problem. I had added several member variables to my subclass, so I had some initialization that I needed to do before the server ran. Problem was, calling NanoHTTPD's constructor was the trigger that started the server. But better yet, the creators didn't implement a default constructor. Any constructor I wrote would be forced to call "super(foo, bar)" as its first command, which would send the whole shebang on its merry way to serve the Internet's web page appetite.

There's a lesson to be learned here: never do non-initialization stuff in your constructor. NanoHTTPD didn't follow that rule, so it created a pseudo-final class for anyone in a situation like mine - in other words, completely defeating the purpose of an extend-as-necessary, bare-bones implementation. Pulling the server start code out into a separate method to be called after instantiation would have been trivial to do, yet such a small omission caused a good-sized headache on my end.

Whenever you're tempted to fudge other things into your constructor, remember the name of the method: constructor. It builds things; don't make it do more than that (I'll bet you'd get a hammer to the head if you tried to make a builder run a server anyhow, as you rightly should). When in doubt, extract the code into a public method and let the developers who build on your code decide when to use it. I guarantee they'll thank you.

As for my project, I was fortunate enough that NanoHTTPD was licensed under the Modified BSD license, so it was free-to-modify as well as free-to-use. I finally ended up copying the whole source code over to my project and began directly modifying it from there... no calls to "super" needed.