THE PASZ.COM BLOG

Wednesday, January 25, 2006

Lessons Learned

In December I left a comfortable, full-time web development job at GlobalEnglish, and decided to try to make it on my own as a freelancer. As my goodbye message, I wrote an email detailing some of the things I learned at that job. I thought some of it was worth preserving on my blog.



...I wanted to leave on a positive note by sharing some of the lessons I've learned during my 5½ years here.

Oddly enough, as I sit down to write this, I realize these lessons are the same as those that were taught by Master Yoda, so I'm adding the appropriate quotes. I guess I didn't pay enough attention in Jedi School.

1. Keep it simple.
Yoda: Size matters not. Look at me. Judge me by my size, do you?
Software inevitably evolves toward a state of complexity, and it's our responsibility to simplify things every once in a while. Many bugs are the result of special-case conditions in the code. In some situations it's appropriate to have special cases, but you must always keep in mind that each case you add increases development and testing time. Complexity can also be off-putting for users. There's a reason Google hardly ever changes their minimalist home page.
This is not to say that we shouldn't be ambitious (see Lesson 5), but we should be smart about the way we build things, and we should be alert for unnecessary details that are more trouble than they're worth.

2. See the big picture.
Yoda: Blind we are, if creation of this clone army we could not see.
The nature of a company is that every individual gets wrapped up in their own role, becoming a specialist in particular details of the operation. As a result, it's easy to a) assume everyone else knows what we know, and b) not be aware of what other people are up to. Therefore, it's a good idea to take a step back and look at the big picture.

3. Don't get distracted by elephants.
Yoda: Attachment leads to jealousy. The shadow of greed, that is.
We can't expect that a single business deal is going to come along and be the answer to all our financial needs. It is tempting to think we can capture the largest "elephants" we see on the horizon, but there's a good chance they'll end up running us around in circles. It's important to keep our eyes open for opportunities, but we shouldn't let them side-track us from our mission, or consume too many of our finite resources.

4. The final 10% takes 90% of the effort.
Yoda: Ready are you? What know you of ready? For eight hundred years have I trained Jedi. My own counsel will I keep on who is to be trained. A Jedi must have the deepest commitment, the most serious mind. This one a long time have I watched. All his life has he looked away... to the future, to the horizon. Never his mind on where he was. Hmm? What he was doing. Hmph. Adventure. Heh. Excitement. Heh. A Jedi craves not these things. You are reckless.
The devil is in the details. This maxim has applied to every project I've worked on. When you start a new feature, you experience a rush of excitement as the idea is brought to life. You tackle the most challenging hurdles head on, and most of the time can find elegant solutions to the big problems.
As it turns out, tackling the big, obvious problems is the easy part. Usually it's something minor an unexpected that causes the most headaches near the end of a project. Like Yoda says, it is reckless to drive forward without taking into account the seemingly insignificant details that could ruin your plans.

5. Don't be daunted by what may appear impossible.
Yoda: Do or do not. There is no try.
If you'd told me 5 years ago that with a small team, we would build a massive, Flash-based site with high-quality audio and animation, I would have said, "That seems unlikely."
If you'd said this site would feature three Courses, hundreds of interactive Activities, and it would be translated into 4 Asian languages, I would have chuckled and said, "Yeah, sure it will."
If you'd added that we'd also have Adventure Quests, a token economy, customizable user shops, and 1000s of tradable treasures, I would have said "Now you're just talkin' crazy!"
GlobalEnglish Kids reached these goals and more because we believed in the product and were willing to work hard to see it through.

Tuesday, January 24, 2006

Making Sense of Event Listeners

I've always had some trouble conceptually with Listeners. I remember first hearing about them in a Java class, and my opinion was that they were cumbersome. Java 1.0 veterans will remember that the initial version of Java didn't even have Listeners. To define an event handler, all you had to do was override the appropriate method in the application or applet class. So to define an event handler for when the mouse button is pressed, you'd write

public boolean mouseDown(Event evt, int x, int y){
//handle event
}


Simple!

To catch a mouse press in Java 1.1 and above, you have to
1. Make sure your application implements the MouseListener interface
2. Tell the application to listen to its own mouse events: addMouseListener(this);
3. Define a mousePressed() method

I'm sure the designers of Java had some good architectural reasons for switching over to Listeners, but as a novice programmer -- still getting a handle on Interfaces -- I found the change baffling. How was it an improvement when something that used to take one step now took 3?

Similarly, when Flash MX came out, I was perplexed to find that they too were adopting a Listener model (though they still supported simple callbacks for legacy reasons). Instead of defining a MouseDown clip event like this

on(mouseDown){
//handle event
}


in Flash MX, one was now encouraged to do the following:

//1. define the listener Object
mouseListener = new Object();
//2. define the event handler method
mouseListener.onMouseDown = function(){
//handle event
}
//3. "subscribe" to the Mouse object so the listener will be notified of Mouse events
Mouse.addListener(mouseListener);


Again, a clumsy 3-step process. I have to admit that to this day, despite the tens of thousands of lines of ActionScript code that I've written, I still have to refer to the Help to remind myself how to set up a Mouse Listener.

Now, even JavaScript is getting into the act with their element.addEventListener() method. I hate to think about all the poor web designers struggling with that one after years of writing "onClick=handleEvent()". It seems like language designers love to copy Java when looking for the best way to do something, but maybe they don't always think through the ramifications on their users...

My point here is not to say that Listeners are bad. However, from a language design standpoint, I feel that for many event-handling situations a simple callback can be cleaner. It makes sense to use Listeners when you need to have multiple objects responding concurrently to the same event. That is, there is a one-to-many relationship between an event and the event handling object. For example, say you are developing a paint application like Photoshop where you can paint on multiple layers at the same time. In this case, you might want each layer listening independently for mouse events, and responding accordingly.

In smaller programs you usually have a one-to-one relationship between an event and the object that handles the event. In these situations, a simple callback will do, and invoking a Listener is overkill. If you're starting out with event handling, my advice is don't worry about comprehending the subtleties of Listeners. Just paste in the appopriate code whenever you need it, and realize that you're using the equivalent of a sledgehammer to put up a tack.