Friday, August 28, 2009

order matters

When we code, we constantly have to create instances and set their parameters. How should we order statements when we're creating several instances of the same type? Should we create the instances first and then set their parameters?


var mercury : Planet = new Planet();
var venus : Planet = new Planet();
var earth : Planet = new Planet();
var mars : Planet = new Planet();

mercury.moons = 0;
venus.moons = 0;
earth.moons = 1;
mars.moons = 2;


Or should we group together each instance's creation and settings?


var mercury : Planet = new Planet();
mercury.moons = 0;

var venus : Planet = new Planet();
venus.moons = 0;

var earth : Planet = new Planet();
earth.moons = 1;

var mars : Planet = new Planet();
mars.moons = 2;


Or should we group together constructor calls and settings but leave variable declarations separate:


var mercury : Planet;
var venus : Planet;
var earth : Planet;
var mars : Planet;

mercury = new Planet();
mercury.moons = 0;

venus = new Planet();
venus.moons = 0;

earth = new Planet();
earth.moons = 1;

mars = new Planet();
mars.moons = 2;


I prefer this last approach. It's easiest to read and it groups together the parts of the code I'm most likely to change in tandem. But it's not always possible:


var planets : Array = new [ new Planet(), new Planet(), new Planet(), new Planet() ];

for each ( var planet : Planet in planets ) planet.moons = Math.floor( Math.random() * 10 );


Also, I'd consider a different type of ordering if parameters values of one instance are related to parameter values of another instance:


var mercury : Planet;
var venus : Planet;
var earth : Planet;
var mars : Planet;

mercury = new Planet();
mercury.moons = 0;

venus = new Planet();
venus.moons = 0;

earth = new Planet();
earth.moons = 1;

mars = new Planet();
mars.moons = 2;

mercury.distanceFromSun = 30000000;
venus.distanceFromSun = mercury.distanceFromSun + 30000000;
earth.distanceFromSun = venus.distanceFromSun + 30000000;
mars.distanceFromSun = earth.distanceFromSun + 50000000;


As always, we should remember that the primary job of code is to communicate our intentions to other programmers (sometimes the "other programmer" is the original programmer two months in the future, when he's forgotten his original intentions). So we can often make ordering decisions by thinking about the story we're trying to tell. Compare this ...

"Once upon a time there lived a beautiful princess, an evil dragon, and a brave knight. The princes was 16 years old; the dragon was 200 years old; the night was 28 years old. The princess had blonde hair; the dragon was bald; the knight had red hair. One day, the princess wandered down to the lake. The dragon liked to eat peasants. The knight fought in many tournaments."

... with ...

"Once upon a time there lived a beautiful princess. She was 16 years old and had blond hair. One day she wandered down to the lake. There was also an evil dragon. He was 200 years old, bald, and he liked to eat peasants. Also, there was a brave knight who was 28 years old. He had red hair, and he fought in many tournaments."

There's no right answer. What's important is to think each case through and decide which approach best communicates your intentions.

(Thanks Tim for sparking this topic.)

Wednesday, August 26, 2009

don't pass variables through classes

Sometimes I find myself writing dangerous code like this:


public class UFO
{
public function UFO( alienColor : uint )
{
var alien = new Alien( alienColor );

...
}
}


It's dangerous because I'm passing UFO a parameter that it doesn't use. All it does with that parameter is pass it through to Alien's constructor.

Why is this dangerous? Well, first of all, it makes the code difficult to understand. You're probably not confused my example, above, because I made it purposefully simple. In real-life examples, when I give myself license to pass-through parameters, I tend to pass them through multiple levels:


public class UFO
{
public function UFO( alienColor : uint )
{
var bridge : Bridge = new Bridge( alienColor );

...
}
}

public class Bridge
{
public function Bridge( alienColor : uint )
{
var alien = new Alien( alienColor );

...
}
}


This is also dangerous because it's ugly. You should pass a constructor only the info necessary to construct its class. The construction crew building the UFO and its bridge don't need to know the alien's color.

Finally, it's ugly because it makes testing difficult. alienColor has multiple chances to get messed up (e.g. set to some illegal value) before it reaches its intended target, Alien.

So how should I write this code? Well, UFO doesn't need to know anything about an alien's color. It just needs a completed alien so that it has a pilot (to help it destroy the Earth!). So I should first construct an alien and then pass it to UFO.


var alienColor : uint = 0xFF00FF;
var alien : Alien = new Alien( alienColor );
var ufo : UFO = new UFO( alien );


or, if there's a bridge in the UFO, I should code like this:


var alienColor : uint = 0xFF0000;
var alien : Alien = new Alien( alienColor );
var bridge : Bridge = new Bridge( alien );
var ufo : UFO = new UFO( bridge );

Monday, August 24, 2009

how do you integrate library assets into your code?

I'm curious as to how folks reference library assets in their code. (I'm talking about Flash projects, not Flex projects).

I don't know if I'm doing it the wisest way, but I create a package called flaBridge. In that package, I make a class for each library item. Often the class is empty...


package com.grumblebee.project.flaBridge
{
import flash.display.Sprite;

class CompanyLogo extends Sprite
{
public function CompanyLogo()
{

}
}
}


I then link to this class in the fla Library.

This gives me a placeholder for adding specific functionality. It also stops my IDE (FDT) from complaining that I'm referencing classes that don't exist.

If I'm referencing an instance that's on the fla Stage, I do it this way:

var logo : CompanyLogo = this[ "logo" ]; //on stage

Thursday, August 20, 2009

NaN != NaN

Let's talk about dividing by zero.

As you probably know, in Math the result of dividing a (real) number by zero is undefined. What is the result of division by zero in AS 3.0?

It depends. If you divide a number other than zero by zero, you get Infinity:

trace( 10 / 0 ); //Infinity

trace( 876 / 0 ); //Infinity

If you divide zero by zero, you get NaN (which stand for "not a number").

trace( 0 / 0 ); //NaN

(By the way, to test if the value is NaN, you can't ask "if ( myVar == NaN )." Instead, you have to ask "if ( isNaN( myVar ) )." )

I learned this nuance recently while trying to fix a weird bug. I was setting the scaleX property of a Sprite. The Sprite was a loader bar, and I was setting its scaleX equal to the percent loaded:

bar.scaleX = loaded / total;

When I tested it in Firefox, the bar was totally invisible. I actually expected that, because I hadn't coded the loading process yet. I thought I was correctly calculating the total. In other words, I expected loaded / total to be equivalent to something like 0 / 87.

What I didn't know is that total was also zero. So I was actually doing this...

bar.scaleX = 0 / 0;

Which is the same as...

bar.scaleX = NaN;

But, like I said, I didn't notice a problem, because the bar was doing what I expected -- showing me that zero percent had loaded by being invisible.

I noticed the problem when I checked out my SWF in Internet Explorer. (I had Flash Player 10 installed in both IE and Firefox.) In IE, the bar was not invisible. It was big. It was so big that it filled up the entire screen!

Eventually, I figured out that I was dividing zero by zero. That still didn't tell me why I was seeing a giant bar in IE and no bar in Firefox. But when I set the numbers to, say, 10 / 1 or 6 / 0, the bar looked the same in both browsers. Which is when I learned that, in AS 3.0, zero divided by zero is NaN. And it's when I learned that the IE and Firefox plugins treat NaN differently when it's used to set the scaleX value of a Sprite.

Why would you want to scale a Sprite to NaN? Hopefully, you wouldn't. I did it by accident.

In both browsers, you get fill-the-whole-screen Sprites if you set scaleX to Infinity (which I guess makes sense: the Sprite gets infinitely wide). So my guess is that in Firefox, sprites interpret a scaleX of NaN as zero, whereas in IE they interpret it the same way they interpret Infinity.

Tuesday, August 18, 2009

when null is not null

Having just left the debugging Twilight Zone, I am going to post my findings so that others can profit from my woes.

I had a simple if statement like this:

if ( someValue == null ) trace( "null" );
else ( trace( "not null" );

I expected the value to be null, so I was surprised to see "not null" appear in the output window.

To check my sanity, I added a trace above the conditional:

trace( "someValue == ", someValue );
if ( someValue == null ) trace( "null" );
else ( trace( "not null" );

To my horror, I got this:

someValue == null
not null

After half an hour of tripping in Bizarro World, I noticed those extra spaces before the word "null" in the first trace. This prompted me to take a look at someValue's declaration:

var someValue : String = myFlashVars.someValue;

myFlashVars is, as you might guess, an object containing all the flashVars. I expected someValue to be null, because, while testing, I wasn't passing any vars into the swf.

Okay, I lied. The declaration wasn't this...

var someValue : String = myFlashVars.someValue;

... it was this:

var someValue : String = unescape( myFlashVars.someValue );

Since myFlashVars got set with URL variables (e.g. http://myapp.swf?someValue=foo), I wanted to make sure that any escaped characters in someValue got converted to unescaped ones.

But this causes a problem when there is no myFlashVars.someValue. If there is no myFlashVars.someValue, then myFlashVars.someValue = null.

And, apparently, if you unescape null, you get the string " null".

So my conditional was testing whether " null" is equal to null. And of course it's not.

Wednesday, August 12, 2009

keep logic out of constructors

I'm sometimes tempted to overstuff constructors:


public class AxeMurderer
{
private var _name : String;
private var _crazy : Boolean;

public function AxeMurderer( name : String, crazy : Boolean )
{
_name = name;
_crazy = crazy;

if ( _crazy )
{
for ( var i : int = 0; i < 10000; i++ )
trace( "all work and no play makes Jack a dull boy" );
}
}
}


The overstuffing is the for loop (and possibly the conditional). I clean things up a bit by refactoring to...


public class AxeMurderer
{
private var _name : String;
private var _crazy : Boolean;

public function AxeMurderer( name : String, crazy : Boolean )
{
_name = name;
_crazy = crazy;

if ( _crazy ) writeManifesto();
}

private function writeManfesto() : void
{
for ( var i : int = 0; i < 10000; i++ )
trace( "all work and no play makes Jack a dull boy" );
}
}


But this creates a problem when I write an interface for the class.

Let me pause to say that I try to write my interfaces first, before writing the classes that implement them. That way I'm coding TO an interface. However, in real life that doesn't always happen. Sometimes I can't work out an interface without first writing at least a dummy implementation. In such cases, I go back and write an interface later. At least that I way I have the interface for similar classes.

So, having written the AxeMurderer class, I decide to create an IMurderer interface -- one that has a slightly broader scope than just axe murderers:


public interface IMurderer
{
//Hmmmm....
}


What do I put inside the interface? Looking back at my AxeMurderer class, the only public method is the constructor. That's because I got tempted by a (anti?) pattern: make the constructor build the object by calling a bunch of private methods.

So the interface would be...


public interface IMurderer
{
function AxeMurderer( name : String, crazy : Boolean )
}


But that would force any class that implemented it to have an AxeMurderer method -- terribly inappropriate for a Poisoner or a Strangler!

So, assuming that all types of murders might write a manifesto, I'm going to change my interface to...


public interface IMurderer
{
function writeManifesto() : void;
}


(I'm using a short example to illustrate a point. A real-life IMurderer would insist on methods like Kill(), Spare(), Escape(), Surrender() and BlameItOnJunkFood().)

Now I'll rewrite AxeMurderer as follows:


public class AxeMurderer implements IMurderer
{
private var _name : String;
private var _crazy : Boolean;

public function AxeMurderer( name : String, crazy : Boolean )
{
_name = name;
_crazy = crazy;

if ( _crazy ) writeManifesto();
}

//NOTE: Method now public
public function writeManfesto() : void
{
for ( var i : int = 0; i < 10000; i++ )
trace( "all work and no play makes Jack a dull boy" );
}
}


Note that I'm still calling writeManifesto() in the constructor. That's fine. Some IMurderer classes may choose to automatically write a manifesto; others may choose to only write one if writeManifesto() is called by an external client.

In general, I try to use constructors just for getting necessary external data into the class. Class logic goes elsewhere.

Monday, August 10, 2009

a super solution

Like many developers, I favor Composition over Inheritance. Still, subclassing is a powerful tool, and I can't imagine abandoning it altogether. Knowing its pifalls, I try to make my intentions as clear as possible when I choose to use Inheritance.

When I read other-people's code, I tend to get confused by inherited variables. Say I'm skimming over a class with three members: width, height and color. I read method after method that mentions these members. Then all of the sudden, one lone method mentions position.

Huh? What's position? Why haven't I seen it before? I scroll around, looking for its definition, but I don't find it. Finally, I remember that I'm looking at a subclass. "Oh! Maybe position is defined in its parent class." I flip over to that class and, sure enough, there's position's declaration. (This must be a total nightmare in languages that support multiple inheritance.)

But I've now wasted brain cells on something other than the task at hand (whatever that was). I shouldn't have to go searching for vars.

To fix this in my own code, I'm going to start labeling inherited vars as with the prefix "super."


function foo() : void
{
var someValue : Number = width + super.position.x;
}


If I look at code like that, I know exactly where position comes from.

what a drag

Like most developers, I make little shortcut utilities to help me bypass repetitive tasks. For some reason, though, I'd never bothered to come up with a solution for the tedious work of drag and drop. Nor have I researched anyone else's solution. But recently, I've had to make a lot of Sprites and MovieClips draggable. After the fifth or sixth time I'd added and removed a bunch of listeners, I thought "There's got to be an easier way."

I thought of two: the first was to extend Sprite, creating DraggableSprite. The second was to make a separate class that only handled dragging and leave Sprite's many other duties to Sprite itself. I settled on the latter, reasoning that Sprite was already bloated enough.

Before sharing my solution, let me outline the steps needed to make a Sprite draggable. First, you need a way to detect when the user has mouse-downed on the Sprite. So you have to add a listener for that.

Inside that listener's callback function, you can go head and call startDrag() on the Sprite. But you also need to remove the MOUSE_DOWN listener, because while the user is dragging the Sprite, listening for mouse downs is just burning computer cycles for nothing.

Meanwhile, you have add a listener for MOUSE_MOVE (in case you need to know when the Sprite moves, as you for the thumb control on a slider or scrollbar). You also need to add two MOUSE_UP listeners, one to the Sprite and one to the stage. The stage listener traps for the the user rolling off the Sprite before releasing his mouse button.

In the MOUSE_UP handler, you call stopDrag(), remove all of the above listeners, and re-add the MOUSE_DOWN listener, so that the process can start all over again.

These steps aren't too bad, unless you wind up having to do them over and over. Compare them with using my DragManager class, which you instantiate this way:

var dragManager : DragManager = new DragManger( mySprite );

That's it. mySprite is now dragabble. If you want control over the optional parameters of startDrag() -- lockCenter and bounds -- just pass them to the Dragmanager constructor as additional parameters:

var dragManager : DragManager = new DragManger( mySprite, true, myRect );

Note: lockCenter defaults to false; bounds defaults to null.

Of course, you usually want to do more than just make a Sprite or MovieClip draggable. You also want to know when it starts being dragged, where it moves, and when it stops being dragged. You can detect these things by adding listeners to the DragManager instance.


var dragManager : DragManager = new DragManger( mySprite );
draggManager.addEventListener( DragManager.START_DRAG, handler );
draggManager.addEventListener( DragManager.DRAG, handler );
draggManager.addEventListener( DragManager.STOP_DRAG, handler );

function handler( event : Event ) : void
{
trace( event.type, event.currentTarget.dragger.name );
}



If you run this code, you'll see the following output as you drag and drop your Sprite:

startDrag mySprite
drag mySprite
drag mySprite
drag mySprite
drag mySprite
drag mySprite
stopDrag mySprite

Note that, inside the handler, you can get access to the Sprite being dragged by referencing event.CurrentTarget.dragger.

DragManager has a couple of other tricks up its sleeve. You can disable dragging by calling disableDrag() and re-enable it by calling enableDrag(). You can also re-use the same DragManager by changing which object it controls:

var dragManager : DragManager = new DragManger( myMovieClip );

//later

dragManager.sprite = mySprite;

Note: ordinarily, I wouldn't bother being this thrifty. If I want to make both a Sprite and MovieClip draggable, I just do this:

var spriteDragManager : DragManager = new DragManger( mySprite );
var movieClipDragManager : DragManager = new DragManger( myMovieClip );

But the previous approach is useful if you want only one of the objects to be draggable. DragManagers can manage multiple objects, but only one at a time.

Other properties include lockCenter and bounds, which you can use if you want to change aspects of the drag after it's started. Note that if you do this, you need to disable and re-enable the drag to make the changes take effect:

var dragManager : DragManager = new DragManger( mySprite );

//later

dragManager.disableDrag();
dragManager.lockCenter = true;
dragManager.bounds = new Rectangle( 20, 100, 200, 0 );
dragManager.enableDrag();

Note: disableDrag() removes all listeners from the Sprite, so it's a good cleanup method for eliminating CPU-hogging processes.

It's such a joy to write classes like DragManager. Or, rather, it's a joy to HAVE written them. Once they're done and tested, you know you've cut a piece of tedium out of your life.

Here's the code: http://www.grumblebee.com/grumblecode/DragManager.zip

Wednesday, August 5, 2009

on the use of constructors

I've tried constructing objects in every way imaginable. After reading many books, blog-posts and essays about best-practices, I was swayed by people who argued that the all data an object needs should be fed to it via its constructor. Before coming to that conclusion, I used to write lots of parameter-initialization methods.


public class Spaceship extends Sprite
{
private var _hullColor : uint;
private var _hasLaser : Boolean;
private var _laserColor : uint;

... more private properties ...

public function set hullColor ( value : uint ) : void
{
_hullColor = value;
}

public function set hasLaser( value : uint ) : void
{
_hasLaser = value;
}

public function set laserColor( value : uint ) : void
{
_laserColor = value;
}

... more setter methods ...

public function render() : void
{
... code that draws the space ship ...
}
}


Using this method, I'd create a Space-ship instance as follows:


var ussValiant : SpaceShip = new SpaceShip();
ussValiant.hullColor = 0x666666;
ussValiant.hullShape = HullShape.CIGAR;
ussValiant.hasLasers = true;
ussValiant.laserColor = 0x00cc00;
ussValiant.hasBridge = true;
ussValiant.bridgeColor = 0x666666;
ussValiant.bridgeShape = BridgeShapes.SPHERE;
ussValiant.bridgeSize = BridgeSizes.large;

ussValiant.render();


The trouble here is that it's impossible to tell whether or not I need to set all the parameters or if some of them are optional. Do I need to set them in a particular order? What happens if I set one after calling render? To even know about all the parameters, I have to read through the whole class's API. If, instead, I set all necessary parameters via a constructor, a quick glance at its heading will tell me everything I need to know about parameter order and requirements:


public function SpaceShip( hullColor : uint, hullShape : uint, hasLasers : Boolean = false,
laserColor : uint = 0, hasBridge : Boolean = false,
bridgeColor : uint = 0, bridgeShape : String = "sphere",
bridgeSize = "small" )


The obvious downside to this approach is the unwieldy number of parameters that are stuffed inside the constructor's parentheses. It was this very problem that originally convinced me to write all those setters. I hate overstuffing a constructor, because constructors should take, at most, three parameters.

Why three? Well, it's not a hard and fast rule. It's just an aesthetic. Three, because it's relatively easy to remember three things. After that, it gets harder, at least for my poor, addled brain. Constructors that take four or more parameters are hard to use and hard to read without confusion. Compare the following:

THE BEST KIND OF CONSTRUCTOR:
var puppy : Puppy = new Puppy();

A VERY GOOD CONSTRUCTOR:
var name : String = "Fred";
var monster : Monster = new Monster( name );

A PERTTY GOOD CONSTRUCTOR:
var bread : String = BreadTypes.RYE;
var meat : String = MeatTypes.TURKEY;
var hasMayo : Boolean = true;
var sandwich : Sandwich = new Sandwhich( bread, meat, hasMayo );

A DUBIUS CONSTRUCTOR:
var hasMilk : Boolean = false;
var hasSugar : Boolean = true;
var isIced : Boolean = false;
var size : String = CoffeeSizes.GRANDE;
var coffee : Coffee = new Coffee( hasMilk, hasSugar, isIced, size );

A TERRIBLE CONSTRUCTOR:
var title : String = "Lonesome Parrot";
var genre : GenreTypes.WESTERN;
var stars : Array = [ "Ian McShane", "Michelle Pfeiffer" ];
var director : String = "Stephen Spielberg";
var writer : String = "Thomas Kenneally";
var budget : Number = 50000000;
var hasSequel : Boolean = true;
var movie : Movie = new Movie( title, genre, stars, director, writer, budget, hasSequel );

When faced with the prospect of a terrible constructor, it's tempting to just pass it a value object:


public class MovieData
{
public var title : String;
public var genre : String;
public var stars : Array;
public var director : String;
public var writer : String;
public var budget : Number;
public var hasSequel : Boolean = true;
}


The benefit here is that the constructor now only needs to take in one parameter:

var movie : Movie = new Movie( movieData : MovieData );

The problem with this approach is that the constructor has lost its power to communicate. From looking at its signature, all I know is that it takes in some vague sort of data. I have to look at the value-object class to learn more. And looking at that still doesn't tell me whether or not I need to give every parameter a value or if some are optional.

Sometimes, this is the best I can do. But usually, I can solve this problem by breaking up the class into several smaller classes. In fact, when I feel the need to pass a constructor many parameters -- via raw values or through a value object -- I take it as a sign that my thinking isn't granular enough.

For instance, does it really make sense to have just one monolithic movie class? At the very least, I can break it up into Movie, Metadata and Staff:


public class Staff
{
...

public function Staff( director : String, writer, String, stars : Array )
{
...
}

...
}

public class Metadata
{
...

public function Metadata( title : String, genre : String, budget : Number,
hasSequel : Boolean = false )
{
...
}

...
}

public class Movie
{
...

public function Movie( metadata : Metadata, staff : staff )
{
...
}
}


I'm not crazy about the Metadata class, because it has four parameters, which violates my aesthetic limit. Perhaps I'll leave it as is, though. I'm not dogmatic about the three-parameter rule. However, looking at the parameters, I do have a vague feeling that "budget" is a different sort of beast from "title", "genre" and "hasSequel". I might consider creating a new class called Finances or at least keep that option open in my mind. I know for sure that I don't want to add any more parameters to Metadata! Maybe Metadata itself should take in three parameters, category (title and genre), hasSequels and finances( budget ). Or maybe Metadata should only be about the title, genre and sequels. Maybe Movie should take in metadata, staff and finances.

Regardless of my ultimate decision, my gaol is to keep everything small: small number of parameters, small methods and small classes. Small is good, because small is readable; small is easy to maintain.

This super-modular approach mirrors the way we think. If I ask you to tell me about your best friend, you might say, "His name is Bob. He's a lab technician." Translated to OOP, that's...

var bestFriend : Person = new Person( "Bob", "lab technician" );

But what if I ask you to describe Bob in more detail. You're likely to say something like, "Well, he's been married for ten years and he has a little girl named Sarah. He has brown hair and green eyes. He lives in Seattle." Notice how you broke down your description into categories. You're didn't amorphously describe Bob. You specifically told me about his family, his looks and his location.

You're didn't do this:

var bestFriend : Person = new Person( "Bob", "lab technician", 10, "Sarah", "brown", "green", "Seattle" );

You did this:

var family : Family = new Family( 10, ["Sarah"] );
var looks : Looks = new Looks( "green", "brown" );
var location : Location = new Location( "Seattle" );
var bestFriend : Person = new Person( "Bob", "Lab Technician", family, looks, location );

That's two too-many parameters, but it's more readable and natural than the former version. Maybe name, occupation and looks could be bundled into a class called Description. That would give you...

var bestFriend : Person = new Person( description, family, location );

The goal isn't to come up with the perfect solution. There isn't a perfect solution. The gaol is to continually play around to make your code as simple and communicative as possible.

Monday, August 3, 2009

adobe's mistake: displayObjects need interfaces

Last week, I wrote a function that drew a randomly-colored circle on a Sprite:


function randomColoredCircle( target : Sprite ) : void
{
var color : uint = Math.round( Math.random() * 0xFFFFFF );
var xPosition : Number = 0;
var yPosition : Number = 0;
var radius : Number = 30;

target.graphics.beginFill( color );
target.graphics.drawCircle( xPosition, yPosition, radius );
target.graphics.endFill();
}


To call this function, all I had to do was hand it a Sprite to draw on:


var sprite : Sprite = new Sprite();

randomColoredCircle( sprite );

addChild( sprite );


This worked fine until I suddenly needed to draw a circle on a MovieClip. I couldn't hand a MovieClip to the function, because it specifically requests Sprites:


function randomColoredCircle( target : Sprite ) : void //won't accept a MovieClip


NOTE: a commenter pointed out that MovieClips do, in fact, inherit from the Sprite class, so the above function will work. However, as you'll see (below), the Shape class does not extend Sprite (or vice versa), so the problem remains.

The worst possible solution to this problem is to make another version of the function that's exactly the same, except it draws on MovieClips:

BAD:


function randomColoredCircleOnSprite( target : Sprite ) : void { ... }
function randomColoredCircleOnMovieClip( target : MovieClip ) : void { ... }


Using this approach, I might have to make a third function that draws circles on Shapes. Ugh! This is begging for trouble. What if I decide to make the circles smaller? I would have to remember to update "var radius : Number = 30" in all three functions.

Here's a better solution -- one I would advocate if Actionscript wasn't an object-oriented langiage:


function randomColoredCircleOnSPRITE( target : Sprite ) : void
{
var canvas : Graphics = target.graphics;
randomColoredCircle( canvas );
}

function randomColoredCircleOnMOVIECLIP( target : MovieClip ) : void
{
var canvas : Graphics = target.graphics;
randomColoredCircle( canvas );
}

function randomColoredCircle( canvas : Graphics ) : void
{
var color : uint = Math.round( Math.random() * 0xFFFFFF );
var xPosition : Number = 0;
var yPosition : Number = 0;
var radius : Number = 30;

canvas.beginFill( color );
canvas.drawCircle( xPosition, yPosition, radius );
canvas.graphics.endFill();
}


This works by having separate functions for Sprite and MovieClip objects. All those functions do is to extract Graphics objects from their owners and send the Graphics to another function, one that actually does the drawing. This works, because though MovieClips and Sprites are different classes, a Graphic is a Graphic is a Graphic. I can now easily draw on Shapes by making one more graphic-extraction function:


function randomColoredCircleOnSHAPE( target : Shape ) : void
{
var canvas : Graphics = target.graphics;
randomColoredCircle( canvas );
}


Though this approach moves in the right direction, we can do better. In an object-oriented system, if you want to do the same thing to two related classes, you do it to their parent class. In fact, both MovieClip and Sprite descend directly from DisplayObject. So, in theory, I should be able to elegantly solve my problem (and eliminate all the graphics-extractor classes) by drawing on DisplayObjects instead of MovieClips and Sprites:


function randomColoredCircle( target : DisplayObject ) : void
{
var color : uint = Math.round( Math.random() * 0xFFFFFF );
var xPosition : Number = 0;
var yPosition : Number = 0;
var radius : Number = 30;

target.graphics.beginFill( color );
target.graphics.drawCircle( xPosition, yPosition, radius );
target.graphics.endFill();
}


The variable target can accept any object in the DisplayObject family, so I can call this function as follows:


var sprite : Sprite = new Sprite();
var movieClip : MovieClip = new MovieClip();

randomColoredCircle( sprite );
randomColoredCircle( movieClip );


Unfortunately, this WON'T WORK. I'll get an error telling my that DisplayObjects don't have a property called "graphics." In fact, they don't. This is because though MovieClips, Shapes and Sprites have graphics properties, there are other DisplayObjects that don't. For instance, TextField is a DisplayObject descendant that doesn't have a graphics property. You can't draw on a TextField.

The definition of DisplayObject looks like this:


public class DisplayObject
{
private var _x : Number;
private var _y : Number;
...
//Note: no _graphics property!
}


MovieClip, Sprite and Shape extend DisplayObject like this:


public class MovieClip extends DisplayObject
{
...
private var _graphics : Graphics;
}


TextField extends it like this:


public class TexTField extends DisplayObject
{
private var _embedFonts : Boolean;
private var _text : String;
...
//Note: no _graphics property!
}


So though you can store both a Sprite and a MovieClip in a variable typed to DisplayObject, you can't access the graphics property of that variable, because DisplayObjects don't have graphics.

However, since several of DisplayObject's children DO have graphics properties, you should be able to refer to all those children generically via a common interface. In other words, what Adobe SHOULD have done -- but didn't -- is to define an IDrawable interface like this:


public interface IDrawable
{
//returns the private _graphics property
function get graphics () : Graphics;
}


Then, it should have implemented this interface for MovieClip, Sprite and Shape:


public class MovieClip extends DisplayObject implements IDrawable
{
...
}

public class Sprite extends DisplayObject implements IDrawable
{
...
}

public class Shape extends DisplayObject implements IDrawable
{
...
}


Had Adobe just added that little bit of extra code, we could type variables as IDrawable and not have to worry about whether they were Sprites, MovieClips or Shapes:


var sprite : IDrawable = new Sprite();
var moveClip : IDrawable = new MovieClip();
var shape : IDrawable = new Shape();

randomColoredCircle( sprite );
randomColoredCircle( movieClip );
randomColoredCircle( shape );


The last step to making this work is to rewrite the randomColoredCircle function so that it accepts IDrawable objects:


function randomColoredCircle( target : IDrawable ) : void
{
var color : uint = Math.round( Math.random() * 0xFFFFFF );
var xPosition : Number = 0;
var yPosition : Number = 0;
var radius : Number = 30;

target.graphics.beginFill( color );
target.graphics.drawCircle( xPosition, yPosition, radius );
target.graphics.endFill();
}


This works because ALL IDrawable objects have a graphics property:


public interface IDrawable
{
//returns the private _graphics property
function get graphics () : Graphics;
}


Like I said, we COULD have used this method IF Adobe had just implemented a common interface for all the classes with graphics properties. They should have done this, as it's a standard and good programming technique, but they didn't. However, all is not lost, because we can do it ourselves by extending the MovieClip, Sprite and Shape classes and making sure our new classes implement IDrawable.

Below, I'll show the complete code to do this. It's a small amount of code, involving some empty classes. The classes are empty because we don't want to add anything to them other than the fact that they implement IDrawable. In other words, MySprite is exactly the same as Sprite, except for the fact that MySprite implements IDrawable and Sprite doesn't:


package
{
import flash.display.Graphics;

public interface IDrawable
{
function get graphics() : Graphics
}
}

package
{
import flash.display.Sprite;

public class MySprite extends Sprite implements IDrawable
{

}
}

package
{
import flash.display.MovieClip;

public class MyMovieClip extends MovieClip implements IDrawable
{

}
}

package
{
import flash.display.Shape;

public class MyShape extends Shape implements IDrawable
{

}
}


That's it. Now I just need to use MyShape, MySprite and MyMovieClip instead of Shape, Sprite and MovieClip, and I'll be guaranteed that all of my classes will implement a common interface:


var sprite : MySprite = new MySprite();
var movieClip : MyMovieClip = new MyMovieClip();
var shape : MyShape = new MyShape();

randomColoredCircle( sprite );
randomColoredCircle( shape );
randomColoredCircle( movieClip );


MyShape, MySprite and MyMovieClip have all properties and methods of Shape, Sprite and MovieClip (width, rotation, etc.), because they inherit those properties from the classes they extend.

Even if you don't ever need to treat Sprites, Shapes and MovieClips as if they are all the same type of objects, I hope my approach shows off the usefulness of common interfaces. If you have several classes that share similar traits, it's key that you relate those classes via inheritance and/or an interface. Doing so will make your code much more extendible for future projects.

Sunday, August 2, 2009

rounding cornders

Whenever possible, I draw with code instead of with Flash's drawing tools. I do this because (a) it allows me to make dynamic changes to shapes at run-time, and (b) because it keeps all the app-construction info in one place (in the code), not split between the code and the stage or library.

But I keep needing shapes with rounded corners. Actionscript has a built-in rounded-corner rectangle class (graphics.drawRoundedRect), but that's the only rounded-cornder method available. I often need rounded-corner triangles, rounded-corner tooltips and rounded-corner circles (just kidding on that last one). So I decided to create a method that allowed me to round the corners of any shape.

I knew I'd need math, which is not my strong point. So I ignored that problem and focused on how I'd create rounded corners with a Bezier-pen tool. Think of the top of a triangle: imaging making points on both of the lines that meet at the top (the apex). If those points are down a little from the top, they can act as start and end points for a Bezier curve. In the illustration, below, I've drawn the start and end points as red dots.

A point at the apex (blue dot) can act as a control point, giving you all the points you need to draw a curve:



Note: Actionscript's Bezier curves have just one control point. The curve is the widest-possible path that Flash can draw without it crossing outside the triangle formed by the start, end and control points.

With this approach, I could make a rounded-cornered shape by starting with a straight-cornered shape and calculating a Bezier curve for each corner.

The first step would be to figure out how to plot points that are a little ways in from the ends of all the lines, as shown by the red dots, above. Generalizing this, I needed a way to find a point on a line. Which is where math reared its ugly head. Luckily, google exists for moments like this. Before long, I found a formula and turned it into a nifty function:


function pointOnLine(t : Number, point1 : Point, point2 : Point ) : Point
{
var xResult : Number = point1.x + ( t * ( point2.x - point1.x ) );
var yResult : Number = point1.y + ( t * ( point2.y - point1.y ) );
return new Point( xResult, yResult );
}


You can use this function by first creating two points that make up a line...


import flash.geom.Point;

var start : Point = new Point( 100, 100 );
var end : Point = new Point( 100, 500 );


... and then handing the points to the pointOnLine function. You also have to hand it t, which is a number between 0 and 1. A t of zero returns the start-point of the line; a t of .5 returns the mid-point of the line. A t of 1 returns the end-point of the line. And so on. So to get a point close to the end of the line, I could call the function like this:


var nearEnd : Point = pointOnLine( .8, start, end );


That out of the way, I could now calculate all the start and end points I needed by calling pointOnLine() twice for each line in my shape, e.g.


//note that I'm using .2 and .8 for t
var nearStart : Point = pointOnLine( .2, start, end );
var nearEnd : Point = pointOnLine( .8, start, end );


Here's an illustration of nearStart and nearEnd for one lines on a triangle:



Now all I had to do was to loop through all the lines on the triangle to find the rest of the start and end points:



After that, it was easy to find the corner points, since they were used to define the triangle in the first place:



I then drew curves through each group of start-end-corner points with the built in curve-to function:


graphics.moveTo( start.x, start.y );
graphics.curveTo( control.x, control.y, end.x, end.y );




In the illustrations here, I've drawn the triangle so you can understand my thought process. In fact, my code never draws the straight-edge version. If it did, it would have to go back later and erase the non-curvy corners. Instead, it draws actual lines from the two inset points of each virtual line: e.g. lines from the .2 t to the .8 t of each line.



If I go through the same process with the t values adjusted to move the pointOnLines in a little, say .4 and .6, I get something like this:



I packaged up my code in a utility class called RoundedShapes. To use it, you call its draw() method as follows:


RounedShapes.draw( target, roundness, points );


The target parameter is the display object on which you want to draw. It can be any object with a graphics property: e.g. Sprite, MovieClip or Shape.

The roundness parameter is essentially t. Roundness must be a number between 0 and 1, 0 being the same as straight.

The points parameter is an array of Points, defining the straight-corner version of the shape.

To draw a rounded-corner triangle, you could use code like this:


import com.grumblebee.ui.drawing.RoundedShapes;

var sprite : Sprite = new Sprite();
var points : Array = [ new Point( 320, 10 ),
new Point( 420, 80 ),
new Point( 320, 160 ),
new Point( 320, 10 ) ];

var roundness : Number = .2;

sprite.graphics.lineStyle( 2, 0x000000 );
sprite.graphics.beginFill( 0xFF0000 );
RoundedShapes.draw( sprite, roundness, points );
sprite.graphics.endFill();
addChild( sprite );


Here's a swf with some example shapes drawn by RoundedShapes.draw(). Just for fun, I animated the roundness parameter of the star:







Here's a link to the RoundedShapes class and an example fla. Happy rounding!

Saturday, August 1, 2009

the beauty of interfaces

= my humble origins =

For my first few years as a programmer, I had a hard time understanding interfaces.

Before continuing, let me explain what I mean by "interfaces," since people use the word in several ways. I'm not talking about user interfaces (buttons and the like). I always understood those. I'm talking about formal interfaces in Actionscript (and similar structures in other languages), the kind you define like this:

public interface MyInterface {}

I understood how to define an interface. That's easy, as I showed above. And I understood how to use one:

public class MyClass implements MyInterface {}

What I didn't understand was the point of interfaces. So I just never used them, and my programs seemed to work. So I couldn't see what interfaces would add to the mix.

Every once in a while, I heard sayings like, "Program to an interface, not to an implementation," and I'd just shrug and move on. (Actually, that saying really confused me. I couldn't get past "Program to". What did it mean to "program to" something? I understood "program for," as in "program for money" and "program by," as in "program by starting with small methods first," but what on Earth did "program to" mean?)

When I read programming books, they rarely seemed to be written for me. Like most Actionscript developers, I had worked my way up to programming via design and animation. Most of my projects were small and didn't involve a team. But the books I read were constantly talking about large-scale applications and the need to clarify your code so that other team-members could understand it. "Don't name a variable 'a'," those books told me, because 'no one will understand what that means.'" That didn't really resonate with me, because as the lone programmer on small projects, I could easily remember what my variables meant, even if I gave them cryptic names.

What no one told me is that small-time programmers gradually morph into big-time programmers. Before I knew it, my bosses and clients were asking me to add many new features to my programs, and those programs started to grow larger and larger. I found myself writing dozens of lines of code, then hundreds, then thousands... This change happened so gradually that I didn't notice it until I was knee deep in variables named "a," "foo" and "a2".

By the sixth week of a project, I couldn't understand what I had coded on the first week. Worse, sometimes my clients would ask me to add features to a project I'd shelved a year ago. When I dusted it off and looked at the code, it seemed to be written in Swahili.

= I am a team of one =

One day it dawned on me that I DID work on a team! My team was comprised of me last week, me last year, me yesterday, me today and me two months from now. And I'd get really pissed off at the me from last week if he didn't leave the code-base tidy, so that the me from this week could easily navigate through it. Many coders do, in fact, work on teams of multiple people. Most of the time, I still work alone. But I've come to realize this doesn't matter. It's just as important for me to write clean code for myself as it is for someone at Microsoft or Adobe to write clean code for their co-workers.

= what is clean code? =


"Writing clean code" means at least two things:

1. Writing code that rarely has to be examined.
2. Writing code that, if it DOES have to be examined, is easy to understand.

Point one means that coding is a form of organized forgetting. If it takes me five hours to write a complex sort routine, I don't ever want to have to look at its guts again. So I make sure it works and then stuff it in a function called sort(). That name is the only part of the routine that the future me should need to worry about. As far as he's concerned, the function looks like this:


function sort( array : Array ) : Array
{
blah blah blah (it just works...)
}


But, because it's impossible to predict the future, there's a chance that the me of tomorrow might have to dig into the sort()'s guts. So I owe it to him to make the actual steps of the routine clear, too. That's the second point, above.

Sometimes I morbidly think of programming as if I'm making my will. I don't want my loved ones to be bothered by it while I'm alive. I just want them to know it exists. When I die, I want it to be easy to execute without anyone having to go through a lot of legal hassle. But if, for some reason, someone absolutely needs to examine it under a microscope, I want them to see that my will is well ordered, all i's dotted; all t's crossed.

= what is a programmer's job? =


Even when I first realized the import of clean code, I thought a programmer's job was to first make sure his program worked and only second to make sure it was easy to read. Over time, I realized that the opposite is true. My programs should first and foremost be easy for humans (including me next month) to read. Why? Because I'm inevitably going to spend more time debugging my programs than I spent writing them, and debugging is horrible (and costly in terms of man-hours) if the code is messy. Yes, it's important that a program works. But if the code is clean, it should be relatively easy to get it working if it's broken. But if the code is messy, it's hard to keep it from breaking and nearly impossible to fix it when it does break.

Have you ever had the horrible experience of fixing a bug and then finding that your fix caused another bug? And then fixing THAT bug and discovering that your second fix caused a worse bug? That's the horror of messy code. That doesn't happen with clean code.

= what does clean code look like? =

Clean code looks like anything else that's clean and organized:

"A place for everything and everything in its place."

This means making clear separations between parts: it means that you shouldn't write a class called GameAndHighScoreManager. You should write one class called GameManager and another called HighScoreManager; it means that you shouldn't write a function called moveCowboysAndIndians(); you should write one function called moveCowboys() and another called moveIndians().

And it means that you should separate interfaces from the implementations.

== what is an iterface? ==


An interface is the public parts of a class. It allows other classes to interact with that class. If there's a class called Human and a class called Dog, what parts of Dog does Human need to know about? (What parts of Dog do I have to think about while I'm programming Human? What parts of Dog can I forget about?) Human needs to feedDog(); he needs to walkDog(); he needs to know isDogAsleep(). However, he doesn't need to digestDogsFood() or makeDogsHeartBeat().

Class definitions give us an easy way to make some methods accessible while keeping others private, as I do here:


public class Dog
{
public function feed( food : Food ) : void { ... }

private function digest() : void { ... }

...
}


The problem with this is that I haven't separated my interface from its implementation. It's like a car that you have to drive by fiddling directly with the parts under the hood. Making some of those parts private is a good idea. But it's a bad idea to make other parts public by cutting strategic holes in the hood. Rather, a car should have an interface that's completely separate from its implementation. In fact, cars do. In a car, these interfaces are called dashboards. If you open a car's hood, you don't see little labels that say "public" and
private." Everything under the hood is private. Unless you're an expert, you should only be operating a car via its interface: the dashboard.

Alas, in the case of Dog, both interface and implementation are in the guts of the class. This can lead to some very confusing problems. For instance, let's say my Human class winds up feeding his dog:


public class Human
{
public function feedDog( dog : Dog ) : void
{
var kibbles : Food = new Food( "kibbles" );
dog.feed( kibbles );
}
}


Everything should work fine unless some idiot -- e.g. the future me -- starts screwing around inside the Dog class.

Well, actually there's a lot I can do inside that class without causing a problem. For instance, I can change...


public function feed( food : Food ) : void
{
yum yum yum...
}


to...


public function feed( food : Food ) : void
{
yuck yuck yuck...
}


Because Human doesn't care about the innards of feed(). All Human cares about is calling the method. Once called, it's free to like or dislike it's food, without affecting Human.

But what if I change food's parameters?


public function feed( foodType : String, calories : int ) : void
{
blah blah blah...
}


I've now broken Human:


public class Human
{
public function feedDog( dog : Dog ) : void
{
var kibbles : Food = new Food( "kibbles" ); //this no longer works
dog.feed( kibbles );
}
}


I could also break Human by renaming Dog's feed method to chew() or bite().

If you take your car in to be repaired, you probably won't be upset if the mechanic changes things around under the hood, as long as your car works when you get it back. You won't even know what changes he made. However, if he messes with the interface -- if he removes the steering wheel and sticks the break pedal in the glove compartment -- you'll be confused and angry. Similarly, Human has a right to be angry, because Dog has changed his interface. But I can't really blame Dog. After all, his interface is inside him. It's not really an interface, it's just part of his implementation that's been labeled public.

= making a formal interface =


So how do we give Dog an real, dashboard-like interface? In Actionscript, we do it like this:


package
{
public interface IDog
{
function feed( food : Food ) : void;
function walk() : void
}
}


By convention, interface names begin with a capital I. Inside the body of an interface, you list the signature of each public function (e.g. all the items on the dashboard). You don't label them "public," because everything in the interface is public -- that's the whole point of an interface. You don't list the body of the functions, because bodies are filled with implementation details. Implementation details do not belong on interfaces.

Now, I can tie my Dog class to this interface as follows:


public class Dog implements IDog { ... }


Anyone who wants to use my Dog class shouldn't bother looking at it's source code. Instead, they should look at its interface. It's interface contains everything users need to know. Dog itself is just a confusion of details. Users should...

... program to the interface, not the implementation!

By saying that Dog "implements IDog," that class is making a promise. It's promising to conform to the rules of IDog. It's saying, "Regardless of how I digest my food and whether or not I like it, you'll always be able to feed me via my feed method. I reserve the right to change how feed is implemented at any time, but I won't change the method name, the parameters it takes in, or what it returns. And, as a user, that's all you should care about."

= an interface is a promise =

I remember when I first read that an interface is "a kind of promise." I was confused. What happens if I break the promise? If it's just a promise, can't I just promise not to change method names or alter their kind and number of parameters? Sure, I can, but there's nothing to stop me if I break my promise. On the other hand, if I type in my code that Dog "implements IDog," I'll get a compile error if I don't keep my promise. For example, if I change Dog's feed method to this:


public function feed( foodType : String, calories : int ) : void
{
blah blah blah...
}


My code won't compile, because IDog says it should look like this:


public function feed( foodType : String, calories : int ) : void
{
function feed( food : Food ) : void;
}


And, in a good IDE (e.g. Flex Builder -- a.k.a. Flash Builder -- or FDT), I won't have to wait until compile time. Most IDEs tell you if you're not following an interface as you type your code.

So a real nuts-and-bolts reason to use interfaces is that they catch errors before the errors happen!

By the way, this doesn't mean that I can't change interfaces. I can. If I want to change the feed() method, I can go into IDog and redefine it. As with all aspects of code, interfaces evolve over time. The good news is that when you make changes to an interface, you get advanced warning about problems you might be causing. You can fix those problems before they rear their heads.

= advanced interface tricks =

Once you get the hang of interfaces, there are some useful advanced features worth using. For instance, interfaces can inherit from other interfaces:


public interface IMachine
{
function turnOn() : void;
function turnOff() : void;
}

public interface ITransporter extends IMachine
{
function beamUp( person : Person ) : void;
function beamDown( person: Person ) : void;
}


And classes can implement multiple interfaces:


public interface IKillable
{
function stabMe() : void;
function shootMe() : void;
}

public interface ITameable
{
function petMe() : void;
function feedMe() : void;
}

public class Shark extends Creature implements IKillable { ... }
public class Demon extends SupernaturalBeing implements ITamebale { ... }
public class Wolf extends Creature implents IKillable, ITameable { ... }


Note: it's another convention it name intefances I-something-able.

= interfaces can be used as types =

Coolest of all, you can type variables to interfaces instead of implementations. For instance "var dog : IDog" instead of "var dog : Dog". Here's a more complete example:


public interface IOpenable
{
function open() : void
}

public class Box implements IOpenable
{
public function open() : void { trace( "There's money inside!!!" ); }
}

public class Skull implements IOpenable
{
public function open() : void { trace( "There's a brain inside!!!" ); }
}

public class Door implements IOpenable
{
public function open() : void { trace( "Nothing to fear. Come on in!" ); }
}

public class DocumentClass
{
//notice how I typed the variable aThing
private function openAThing( aThing : IOpenable) : void
{
aThing.open();
}

//constructor
public function DocumentClass()
{
var box : Box = new Box();
var skull : Skull = new Skull();
var door : Door = new Door();

openAThing( box ); //There's money inside!!!
openAThing( skull ); //There's a brain inside!!!
openAThing( door ); //Nothing to fear. Come on in!
}
}


The magic here is that box, skull and door are three totally unrelated classes. They aren't children of the same base class. But they all share the same interface. So as long as you type a variable to IOpenable, that variable can store any of those classes.

= start your projects with interfaces =

Creating interfaces is a great way to start a project (you'll refine those interfaces as you go). If all you have at the beginning is interfaces, what else can you do except "program to interfaces"?

A great way to think about an Object Oriented system is as a bunch of things all talking to each other, pushing each other, pulling each other, etc. As such, each of these things can only interact with another thing through its interface. So you don't need to know anything about implementation details in order to describe the whole system. You just need to know the public face of each thing.

As an example, lets say that I'm making a Pacman game. I know nothing (yet) about how the objects will work, but I know that I'll need a maze, some dots (for the Pacman to eat), a Pacman and some ghosts to chase him and be chased by him. (To keep this example simple, I'll ignore other details, such as scores, lives and levels).

Opening my editor, I'll make a first draft at the interfaces:


public interface IPackman
{
function move( direction : String ) : void;
function eatDot() : void;
function eatGhost() : void;
function render() : void;
}

public interface IGhost
{
function move( direction : String ) : void;
function eatPackman() : void;
function avoidPackman() : void;
function returnToBase() : void;
function render() : void;
}

public interface IMaze
{
function render() : void;
}

public interface IDot
{
function render() : void;
}


== draft two ==


Looking over my initial draft, I notice that both Packmen and Ghosts can move and eat. And everything seems to be renderable, which makes sense in a visual system. So I redraft my interfaces to group similar methods together:


public interface IRenderable
{
function render() : void;
}

public interface IMovable
{
function move( direction : String ) : void;
}

public interface IEater
{
function eat( food : IEdibleObject ) : void;
}


When I later define my classes, they will all implement IRenderable. Packman and Ghost will both implement IMovable and IEater.

Notice the reference to IEdibleObject inside IEater's eat method. I need to define that, too:


public interface IEdibleObject
{

}


= empty interfaces =

Sometimes I create empty interfaces. At this point in development, all I know is that a bunch of different kinds of things -- packmen, ghosts and dots -- are all edible. I'm not sure if editable object will need to implement any common methods. And maybe they should all be descended from a base class instead of (or in addition to) implementing a common interface. But at this point, the empty interface serves to remind me that this is a sensible way to group certain objects. If I later decide to add a digestMe() method inside IEdibleObject, my IDE will remind me that I need to implement in this in all classes that are implementing it.

To wrap thing up (for now), I'll add the following definitions to my list of interfaces, though I expect I'll make more drafts when I start working on implementation:


public interface IEnemy
{
function returnToBase() : void;
function avoid( target : IGamepiece ) : void
}

//for dots, packmen, ghosts, etc. Do I need this AND IEdible?
public interface IGamepiece
{

}


= interfaces and class inheritance =

Sometimes I wind up using both interfaces and class inheritance. This happens when I want a whole family of classes to implement an interface in the same way:


//this class will never be instantiated as an object,
//which is why I have named it starting with the prefix "Abstract"
public class AbstractCreature implements IMoveable, IRenderable, IGamepiece
{
public static var STEP : int = 50;

//IRenderable forces me to include this method
public function render() : void
{
//override in subclasses
}

//IMovable forces me to include this method
public function move( direction : String ) : void
{
if ( direction == "up" ) this.y += STEP;
else if ( direction == "down" ) this.y -= STEP;
else if ( direction == "left" ) this.x -= STEP;
else if ( direction == "right" ) this.x += STEP;
//note: I'm not suggesting that this is how you'd
//animate a packman or ghost in real life.
}
}

public class Packman extends AbstractCreature
{
override public function render() : void
{
drawCircle();
cutPieSliceOutOfCircle();
animateMouthOpeningAndClosing();
}

private function drawCircle() { ... };
private function cutPieSliceOutOfCirce{ ... };
privare function animateMouthOpeningAndClosing{ ... };
}

public class Ghost extends AbstractCreature
{
override public function render() : void
{
drawBody();
drawEyes();
}

private function drawBody() { ... };
private function drawEyes() { ... };
}


I don't have to explicitly state that Packman and Ghost extend the interfaces IMovable and IRenderable, because they inherit that fact from their parent, AbstractCreature. All these classes also implement my empty (for now) IGamepiece interface -- just in case!

Note that the subclasses are free to implement additional interfaces that aren't implemented by AbstractCreature. For instance, if I have an interface called IPlayerCharacter (for the character played by the actual player of the game, as opposed to the AI ghosts), I could have my Packman subclass extend that.

= interfaces, me and Tim =

My relationship with interfaces has gone through three stages: at first I was baffled by them, then I got into them, and now I'm REALLY into them. For my third and current phase ("REALLY into them"), I have my friend Tim to thank. Tim, a seasoned programmer who has worked for Microsoft and programmed in many languages, makes interfaces for (almost) all his classes. Though I loved interfaces before I started talking to Tim about them, my immediate reaction to Tim's process was that he was taking a good thing too far. But the more I thought about it, the more I was unable to come up with an objection to Tim's way of working. If a class doesn't have a formal interface, then all its public methods are mashing up their interfaces with their implementations. That's messy and dangerous. So now I'm born again into the church of Tim.

Tim's idea is a bit revolutionary in Actionscript circles, but it's the norm in some other programming communities and languages. For instance, in Objective-C (a suddenly popular language, since one must use for iPhone development), all classes must have separate interface files. Unfortunately, since Actionscript doesn't force you to use interfaces, many of developers don't bother.

Not every one of my classes (or Tim's) implements an interface unique to itself. In many cases, large groups of classes all implement a single interface. Interfaces are, among other things, a great way of finding and expressing commonality. "I didn't think these classes had anything in common, but now I can see that they all render graphics. I'm going to make an interface called IRenderable and make them all implement it. Later, I can make a grand render-function that takes an array of IRenderable objects, loops through them and calls each of their render() methods!"

= when not to use interfaces =


Like Tim, I don't bother making interfaces for Value-Object classes (a.k.a Data Transfer Objects). If a class is just a collection of public properties...


public class ContactVO
{
public firstName : String;
public lastName : String;
public email : String;
pubic phone : String;
}


... then there's not much of point to making an interface for it. I also don't make interfaces for utility classes, which are generally collections of static methods. I don't really think of such classes as classes. In their cases, "class" is just a cheap and easy way to group together a library of helper functions.

But if something is an object that relates to other objects, it needs an interface. And since virtually everything in an OOP world is an object that relates to other objects, virtually everything in that world should have an interface.