Index: [thread] [date] [subject] [author]
  From: Jason Grosland <jcg3@cs.duke.edu>
  To  : 
  Date: Wed, 28 Apr 1999 02:43:16 -0400

Re: instanceof

Ok, so this whole topic seems to be getting a little confused somewhere.
Here's an attempt to clear up a few things about instanceof:

Using instanceof as a sort of work around for avoiding if/else's (we've
been told that if/else statements are bad) is not a good idea, with regard
to OOP at least.

In other words, if you're doing this:

if(terrain instanceof BumpyTerrain) {
  BumpyTerrain bt = (BumpyTerrain)terrain;
  bt.draw();       // BumpyTerrain specific methods
  bt.drawBumps();
  // etc.
} else if (terrain instanceof SmoothTerrain) {
  SmoothTerrain st = (SmoothTerrain)terrain;
  st.drawOutline();  // SmoothTerrain specific methods
  st.figureCoords();
  // etc.
}

This is what we call bad.  What you should be doing instead should be
something like:

if(terrain != null) {
  terrain.draw();
}

In which case, your BumpyTerrain and SmoothTerrain both know how to draw
themselves according to each class's draw() method.  This is called
polymorphism, which is one of the great benefits of OOP.  We don't need to
know which kind of GameTerrain 'terrain' is, as long as it knows how to
draw itself.

If you need to extract the way something is displayed and it's core
functionality (a good idea, btw), there are many options...

(terrain.getGUITerrain()).draw();  // A GUITerrain was added to your
				   // terrain at some point...

terrain.draw(myGraphics, x, y);  // maybe we need to pass in a place to
				 // draw itself?

world.display(terrain);   // maybe the world is in charge of displaying?


As always, there are several ways to accomplish this, all with specific
benefits and drawbacks.  You should be able to accomplish this kind of
thing without violating general OOP heuristics.  Whatever you decide,
document what you did, and explain why.  If you do something non-OOP, you
should have a very good reason.

Also, instanceof is fine to use in Observer's update code _IF_ update is
getting passed more than one kind of object due to different kinds of
changes.  These should be conceptually different, like the difference
between passing a Canvas and a Command.  Of course, we could also use a
DisplayObserver/DisplayObservable and CommandObserver/CommandObservable
pairing to differentiate the two kinds of observable updates.  What are
the differences?  What are the tradeoffs?  Why would you choose to do it
one way?  These are the design decisions that you need to think about, and
answer on your own for your specific context.

...jason

  { jcg3@cs.duke.edu * www.duke.edu/~jcg3 * 919.613.1354 * 108 House P }



Index: [thread] [date] [subject] [author]