Archive for March, 2012

You’ve been implementing main() wrong all this time

Since the very early days of Java (and C-like languages overall), the canonical way to start your program has been something like this:

public class A {
  public static void main(String[] args) {
    new A().run(args);
  }
  public void run(String[] args) {
    // Your application starts here
  }
}

If you are still doing this, I’m here to tell you it’s time to stop.

Letting go of ‘new’

First, install Guice in your project:

        <dependency>
          <groupId>com.google.inject</groupId>
           <artifactId>guice</artifactId>
           <version>3.0</version>
        </dependency>

and then, modify your main method as follows:

public class A {
  public static void main(String[] args) {
    Injector.getInstance(A.class).run(args);
  }
}

So, what does this buy you exactly?

You will find a lot of articles explaining the various benefits of Guice, such as being able to substitute different environments on the fly, but I’m going to use a different angle in this article.

Let’s start by assuming the existence of a Config class that contains various configuration parameters. I’ll just hardcode them for now and use fields to make the class smaller:

public class Config {
  String host = "com.example.com";
  int port = 1234;
}

This class is a singleton, it is instantiated somewhere in your main class and not used anywhere else at the moment. One day, you realize you need this instance in another class which happens to be deep in your runtime hierarchy, which we will call Deep. For example, if you put a break point in the method where you need this config object, your debugger would show you stack frames similar to this:

com.example.A.main()
com.example.B.f(int, String)
com.example.C.g(String)
com.example.Deep.h(Foo, int)

The easy and wrong way to solve this problem is to make the Config instance static on some class (probably A) and access it directly from Deep. I’m hoping I don’t need to explain why this is a bad idea: not only do you want to avoid using statics, but you also want to make sure that each object is exposed only to objects that need them, and making the Config object static would make your instance visible to your entire code base. Not a good thing.

The second thought is to pass the object down the stack, so you modify all the signatures as follows:

com.example.A.main()
com.example.B.f(int, String, Config)
com.example.C.g(String, Config)
com.example.Deep.h(Foo, int, Config)

This is a bit better since you have severely restricted the exposure of the Config object, but note that you are still making it available to more methods than really need to: B#f and C#g have really nothing to do with this object, and a little sting of discomfort hits you when you start writing the Javadoc:

public class C {
  ...
  /**
   * @param config This method doesn't really use this parameter,
   * it just passes it down so Deep#h can use it.
   */
  public void g(String s, Config config) {

Unnecessary exposure is actually not the worst part of this approach, the problem is that it changes all these signatures along the way, which is certainly undesirable in a private API and absolutely devastating in a public API. And of course, it’s absolutely not scalable: if you keep adding a parameter to your method whenever you need access to a certain object, you will soon be dealing with methods that take ten parameters, most of which they just pass down the chain.

Here is how we solve this problem with dependency injection (performed by Guice in this example, but this is applicable to any library that implements JSR 330, obviously):

public class Deep {
  @Inject
  private Config config;

and we’re done. That’s it. You don’t need to modify the Config class in any way, nor do you need to make any change in any of the classes that separate Deep from your main class. With this, you have also minimized the exposure of the Config object to just the class that needs it.

Injecting right

There are various ways you can inject object into your class but I’ll just mention the two that, I think, are the most important. I just showed “field injection” in the previous paragraph, but be aware that you can also prefer to use “constructor injection”:

public class Deep {
  private final Config config;
  @Inject
  public Deep(Config config) {
    this.config = config;
  }

This time, you are adding a parameter to the constructor of your Deep class (which shouldn’t worry you too much since you will never invoke it directly, Guice will) and you assign the parameter to the field in the constructor. The benefit is that you can declare your field final. The downside, obviously, is that this approach is much more verbose.

Personally, I see little point in final fields since I have hardly ever encountered a bug that was due to accidentally reassigning a field, so I tend to use field injection whenever I can.

Taking it to the next level

Obviously, the kind of configuration object I used as an example if not very realistic. Typically, a configuration will not hardcode values like I did and will, instead, read them from some external source. Similarly, you will want to inject objects that can’t necessarily be instantiated so early in the lifecycle of your application, such as servlet contexts, database connections, or implementations of your own interfaces.

This topic itself would probably cover several chapters of a book dedicated to dependency injection, so I’ll just summarize it: not all objects can be injected this way, and one benefit of using a dependency injection framework in your code is that it will force you to think about what life cycle category your objects belong to. Having said that, if you want to find out how Guice can inject objects that get created at a later time in your application life cycle, look up the Javadoc for the Provider class.

Wrapping up

I hope this quick introduction to dependency injection piqued your interest and that you will consider using it in your project since it has so much more to offer than what I described in this post. If you want to learn more, I suggest starting with the excellent Guice documentation.

Video game update

I haven’t talked about video games in a while, so I thought I’d put together a short summary of what I played this past year, in no particular order.

The original Deus Ex is considered to be one of the best PC games of all times (along with another one mentioned below), so developing a sequel more than ten years later is quite a tall order. From what I can see, DXHR manages to pull it off. I played about one third through the game and then put it away with the firm intention to go back to it (a pattern that seems to be recurring in my gaming habits).

I don’t think Portal needs any introduction, and nobody actually expected a sequel to the best PC game of all times (according to PC Gamer) to be able to measure up. This is why Portal 2 was such a delightful surprise to me, and in hindsight, I think it’s better than the first episode in all respects. On top of inventing new creative puzzles, Valve managed to actually imagine a very poignant and appealing story that I absolutely fell in love with. I replayed the game three times and I suspect that I will do so again on a regular basis in the years to come. The characters, their acting and voices are also incredibly well done and downright funny despite the tense scenario, and I don’t think anyone will be able to forget the Stephen Merchant / Ellen Mc Lain duo for a long time.

I have always been a Civilization fan, going back to the very first installment of the series and its insanely punishing difficulty. Civilization V doesn’t betray the series and streamline a lot of the rough edges that players complained about in the previous version. List most Civilization, I have the feeling I barely scratched the surface of this one and I’m looking forward to going back to explore it further. In my book, however, Civilization IV remains the best of the entire series.

Referring to this little gem as “Minecraft in 2D” is not doing it justice. It shares some crafting and discovery ideas with Minecraft, but the resemblance stops there. In this 2D platformer, you craft to create stronger weapons and armors so you can explore further away from your base. That’s about the extent that I know of it, I only spent an hour or so on it but I definitely want to see how far that rabbit hole goes. The developers recently announced that they were moving on, but there is already enough material in the current release to keep someone playing for a long, long time (some fans have clocked more than 100 hours on this game).

While I did buy Oblivion on the day it came out, I felt that I never really explored all that it had to give because I was extremely turned off by the clunky, obviously console targetted, UI. While I think that Skyrim is one of the best games I’ve played these past years, I’m sad to report that it suffers from the exact problem as Oblivion. However, the UI is not irreparably damaged that it makes playing it on a PC impossible, so after some tweaking, I was able to play the game in a reasonably satisfying manner. In one sentence, Skyrim is what World of Warcraft would be if it weren’t a multiplayer game.

I spent about thirty hours on it and reached level 20 while barely touching the main quest line (and I had a tremendous amount of fun doing so). And then my excitement and interest waned. Again, I really want to go back to it, if only to finish the main quest and visit some of the gorgeous locations I’ve heard of, such as Black Reach, so I really hope I’ll find enough resolve and time to do so.

Rift recently became free to play, so why not try it? I did but after an hour spent in the beginner zone, I can’t say I felt compelled to push further. Admittedly, this is no way to assess a MMO game, so I’m aware I might be missing out.

Another attempt at reusing some of World of Warcraft’s successful recipe without the MMO component. The main difference is that the fights are much more action oriented (this game also runs on consoles, after all), so you will find yourself sidestepping, dodging, rolling and also swinging, parrying and triggering various special combinations during your fights. The story line seems to be fairly expansive with a lot of content to go through. I have only spent five hours on this game and it feels like I have barely scratched its surface.

No, I didn’t get the screen shot wrong. I really mean the original X-Com game, released in 1993. I mentioned in the introduction that I would talk about another game ranked among the best of all times, and this is it.

I never really played the original when it came out but given the non stop rants and articles I have read about it during these past two decades, I have always wanted to give it a fair shot. What eventually motivated me was learning that Firaxis was going to create a sequel for it. There have been several sequels to the game but the one that the Firaxis (of Civilization fame) is working on is pretty much guaranteed to be true to the original. Here is one of the two interviews they gave on the subject. These guys mean business.

Back to the original game: it’s very simple to install and play on any OS (thanks to DOSBox) and while I expected some frustration from the punishing user interface, I ended up finding my way through it fairly easily. I only played a few hours and I managed to down my first UFO, so I can’t say that I have experienced what everyone has been raving about, but I think I now have a better idea. I’m hoping I’ll be able to push through a bit further before Firaxis’ version of the game comes out.

Yes, that Ultima 6. Inspired by the riveting reports of the “CRPG Addict” blog, I decided I wanted to replay an Ultima. Since he had just reviewed Ultima 5 and I still felt that Ultima 7 was fresh in my mind (I played it a couple of years ago), I decided to go for Ultima 6. I wasn’t holding much hope, but it didn’t take long for Lord British’s creation of 1990 to completely suck me in again. Next thing I know, I was taking tons of notes and slowly unraveling the mystery of the False Prophet. It was a blast from start to finish, but unfortunately, I didn’t keep track of how many hours I spent on it. I did save all my notes for posterity (the annotated map might come in handy and it doesn’t contain any major spoilers).

Maybe I’ll carry on with Ultima 7, which has several flavors available (I’ve only ever played the first one, so I have at least three to discover before moving on to Ultima 8, which I don’t have fond memories of).

Don’t try, you have probably never heard of this game. It was released in 1984 on the Apple ][ and even back then, it was a pretty obscure game. Yet, I remember vividly spending hours and hours on it during high school until I finally managed to beat it. For some reason, I thought about this game again recently and I decided to see how well it lived up to my memory.

Like most of the games that came out at the time, it’s pretty hard to describe and bizarre in its own way, but that’s also what makes it very interesting. You are controlling a ship in across a maze made of sixty-four rooms and your goal is to explore all of them. Part of the fun of the game is to uncover its mechanisms and how to unlock doors. Once you have solved the game, you can complete it in less than twenty minutes but to get there, you should expect to spend at most a couple of hours to unravel its mysteries. I have to say I enjoyed playing it this time around and I certainly wish we saw more of these creative and innovative games today.

I actually wrote an extensive review of this absolutely wonderful adventure game last year, so I’ll just refer you there if you are curious. Even if you’re not that much into adventure games, I strongly recommend giving this game a shot, it’s perfect in pretty much all respects and it sits up there with the likes of “Monkey Island”, “Indiana Jones and the Fate of Atlantis” and “Zak Mc Kracken and the Alien Mindbenders”.

Speaking of classics, I spent some time rediscovering the Monkey Island series and I play them whenever there is a bit of a lull in my video games activities. The Monkey Island Special Editions are fantastic, they talk about pirates, they are funny and the entire series is considered the best adventure game saga of all times. What’s not to like?

An indie game that took everyone by surprise last year. The soundtrack is beautiful and it’s hard not to start paying attention to the story as it slowly unfolds through the wonderful Chandler-like narration. Bastion also sits in a niche of its own in terms of game play, with the land assembling ahead of you as you make progress through the levels. It offers various weapons (melee, range and special ability) which can be boosted by elixirs (buffs) and other customizations that you can gain either through the game or by performing well on challenge levels (such as knocking out all the enemies with only fifteen shots of your scrap musket). I must be about one third through the game and while I’m starting to feel a little bit of repetition, I really want to reach the conclusion of this game to find out where it’s taking me.

“You can check out any time you want, but you can never leave”. This probably sums up my relationship with World of Warcraft since 2004. At least, I feel I made a major advance two years ago when I stopped raiding, and at that point, I thought I was pretty much done. Well, it turns out that the devils living in Blizzard’s halls know a thing or two on the multiple ways in which they can hook you to a game, and they certainly managed to pull that trick on me since I became a casual player.

The good news is that I’m no longer spending as many hours as I used to in Azeroth and also that my interest goes in bursts. The latest example is deciding to level a new character and take it to the very end of the game: killing Deathwing. I was curious to find out how long it would take, and while I thought most of it would be a grind, I actually enjoyed goign through the entire journey, probably since it was a good opportunity to find out exactly what changes had been made to the early areas of Cataclysm, but also because the new “Looking for Group” mechanism makes leveling very fast. You basically queue all the time and you then have the choice to either quest or accept the dungeon invitation.

As soon as I met the level 85 gear requirements to queue for the new “Looking for Raid” interface, I did so and one hour later, I had killed Deathwing. It took me about five days played (emphasis on “played”: that’s more than one hundred hours of game time and two-three months of real time) to take my character from level one to end game. And once I was done with this task, I… well, felt absolutely no urge to launch the game again. I’m probably done until the next expansion, the Mists of Pandaria, comes out, at which point I will probably fall for it again.

Conclusion

So this is my video game history of this past year. If there is one thing I’m taking away, it’s that I’m finding it increasingly hard to be interested in a game for extended periods of time, World of Warcraft being the striking and sole exception. I seem to hit a ceiling at twenty or thirty hours, and most of the games I play don’t even make it that far. This year, I’m looking forward to playing Mass Effect 3, Diablo 3 and maybe give Guild Wars 2 a try. Hopefully, I’ll come across a few other interesting games that are not sequels of well established franchises, something that seems all but impossible outside the Windows gaming arena.

Solution to the “Power story” challenge

Here is the solution to the “Power story” non coding challenge:

When the power went out, Ann open the wireless settings of her laptop, scanned the area but couldn’t find a single wireless access point in the neighborhood.

This is actually based on a true story (mine, yesterday). I can usually see a dozen access points at any time, but they were all gone after the power went out yesterday, which gave me the idea for this challenge.

We had a few good answers, some that came close and a few more that answered without reading the problem carefully :-).

I have approved all the moderated comments on the original challenge.

Non coding challenge: a power story

Since the next coding challenge will be a bit brutal, I thought we all earned a little break so here is a short non coding challenge. I’m pretty sure you won’t find the answer on the net since I just made it up…

Ann was enjoying this Sunday morning in her San Francisco apartment by sipping a nice cup of coffee and browsing the web on her laptop and her home wifi connection when the entire apartment went dark. Her husband entered the room:
“I might have tripped a fuse with my computer, I’ll go check the breaker box.”
“Don’t bother, it’s a general outage, the neighbors lost power too.”
“Oh? How do you know? Did you talk to them?”
“No.”
“Did you make a phone call or receive one?”
“No.”
“Did you talk to anyone?”
“Only you.”
“Did you see something outside that tipped you off?”
“No.”

How did Ann know that the outage was general and not just their apartment?

Update 1: I will hold the comments in the moderation queue for a little while to avoid spoilers, but I’ll publish them all shortly.


Update 2: I posted the solution.