Saturday, August 16, 2008

Boba Fett, Greedo, and the Strategy Pattern

bobafett Bounty hunting is a difficult line of work.  Think about it:  1) Jobs are generally consulting gigs rather than full-time employment.   2) You're brought in at the last minute, usually to clean up someone else's mess, under a lot of pressure to save the day.  3) There are long hours, difficult problems to solve, and any benefits or vacation days come out of your own back pocket.  So give Boba Fett and Greedo a little respect.  They're willing to go flying off to the seedy backwaters of the galaxy, at great personal expense, mind you, turning over every stone until they find the Rebel scum they've been told to bring in.  All because the megalomaniacal creeps they work for run huge bureaucratic organizations filled with nothing but boot-licking sycophants and lackeys who can't seem to catch one measly smuggler and his smelly walking-carpet sidekick.  And if they should happen to run across this smuggler, who knows what kind of lethal stunt this half-witted, scruffy-looking nerf herder is liable to pull to get away from them.  Here's just one example:

image 

Shocking, isn't it?  I know.  It's called the StrategyPattern, and if you're not looking out for it, well you might just end up with some brand new ventilation courtesy of Han's blaster.  Here's how it works:

Let's say you find yourself in a particular context, like, say, a cantina on a desert planet.  Bartender gives you a drink, and you're parched, so you reach for it.  But wait!!  Is that beaker really filled with good old Membrosia?  How do you know nobody has slipped the bartender a couple hundred galactic credits along with a bottle marked "Membrosia", but which is really heavily spiked with carsunum?  What does the bartender care?  All he knows is he gets a free bottle and two hundred credits out of the deal - makes no difference to him.  People keel over in his place all the time.  Seems like a pretty good strategy for knocking you off, wouldn't you say?

Here's another strategy pattern scenario I bet you didn't think about:

image

Boba Fett is a bounty hunter. 

   1: public class BountyHunter : ICantinaPatron
   2: {
   3:     private string _name;
   4:     private IList<IStuff> _basket = new List<IStuff>();
   5:  
   6:     public BountyHunter(string name)
   7:     {
   8:         _name = name;
   9:     }
  10:  
  11:     public string Name
  12:     {
  13:         get { return _name; }
  14:     }
  15:  
  16:     public IList<IStuff> Basket
  17:     {
  18:         get { return _basket; }
  19:     }
  20: }

He happens to walk into the Mos Eisley cantina on a day when they're giving away stuff to all the cantina patrons: today, it's fuzzy animals. (Don't ask me.  Some corporate marketing idiot from the cantina's Membrosia distributor thought it would be a good promotional gimmick.) 

   1: public class Cantina
   2: {
   3:     private int _bribe;
   4:     private StuffStrategy _stuffStrategy = new LitterOfKittens();
   5:  
   6:     public void AcceptBribe(int bribe)
   7:     {
   8:         _bribe = bribe;
   9:     }
  10:  
  11:     public void SetStuffStrategy(StuffStrategy stuffStrategy)
  12:     {
  13:         if (_bribe > 100) _stuffStrategy = stuffStrategy;
  14:     }
  15:  
  16:     public ICantinaPatron GetPatron(string name)
  17:     {
  18:         ICantinaPatron cantinaPatron = new BountyHunter(name);
  19:         _stuffStrategy.GetStuff(cantinaPatron);
  20:         return cantinaPatron;
  21:     }
  22: }
  23:  
  24: public abstract class StuffStrategy
  25: {
  26:     public abstract void GetStuff(ICantinaPatron cantinaPatron);
  27: }
  28:  
  29: public interface IStuff
  30: {
  31:     string DoSomething(ICantinaPatron patron);
  32: }
  33:  
  34: public interface IFuzzyAnimal : IStuff
  35: {
  36:     string Name { get; }
  37:     string MakeNoise();
  38:     string Play();
  39: }
  40:  
  41:  

So when Boba Fett takes his basket of stuff from the barkeep and opens it up to see what he got, he discovers a litter of adorable kittens named Blossom, Minty, Butterscotch, Cotton Candy, Blue Belle, Snuzzle, and Rainbow Dash.

   1: public class Kitten : IFuzzyAnimal
   2: {
   3:     private string _name;
   4:     private string _playmate;
   5:  
   6:     public Kitten(string name)
   7:     {
   8:         _name = name;
   9:     }
  10:  
  11:     public string Name
  12:     {
  13:         get { return _name; }
  14:     }
  15:  
  16:     public string MakeNoise()
  17:     {
  18:         return
  19:             "Hi, " + _playmate + "!  My name is " + _name +
  20:             ", and I'm a kitten!  Meow!  prrrrr  prrrrrrrrrrrr";
  21:     }
  22:  
  23:     public string Play()
  24:     {
  25:         return _name + " blinks her big grey eyes and paws " + _playmate + "'s finger adorably.";
  26:     }
  27:  
  28:     public string DoSomething(ICantinaPatron patron)
  29:     {
  30:         _playmate = patron.Name;
  31:         return MakeNoise() + "\r\n" + Play() + "\r\n";
  32:     }
  33: }
  34:  
  35: public class LitterOfKittens : StuffStrategy
  36: {
  37:     public override void GetStuff(ICantinaPatron cantinaPatron)
  38:     {
  39:         cantinaPatron.Basket.Add(new Kitten("Blossom"));
  40:         cantinaPatron.Basket.Add(new Kitten("Minty"));
  41:         cantinaPatron.Basket.Add(new Kitten("Butterscotch"));
  42:         cantinaPatron.Basket.Add(new Kitten("Cotton Candy"));
  43:         cantinaPatron.Basket.Add(new Kitten("Blue Belle"));
  44:         cantinaPatron.Basket.Add(new Kitten("Snuzzle"));
  45:         cantinaPatron.Basket.Add(new Kitten("Rainbow Dash"));
  46:     }
  47: }

Here's what happens when Boba Fett plays with each kitten, and it's just the cutest thing you've ever seen.  Almost brings a tear to your eye:

image

greedo Greedo is also a noble bounty hunter, but he has a dark secret: he just loves fuzzy, adorable kittens!  He's so excited when he sees what Boba Fett got that he completely forgets about the Strategy Pattern!  Oh no!  Greedo beware!  While Greedo is distracted, Han has slipped the barkeep a bribe along with another group of "fuzzy animals":

   1: internal class Program
   2: {
   3:     private static Cantina _cantina;
   4:  
   5:     private static void Main(string[] args)
   6:     {
   7:         _cantina = new Cantina();
   8:  
   9:         GetANewPatron("Boba Fett");
  10:  
  11:         _cantina.AcceptBribe(200);
  12:         _cantina.SetStuffStrategy(new ConfusionOfWeasels());
  13:         
  14:         GetANewPatron("Greedo");
  15:  
  16:         Console.Read();
  17:     }
  18:  
  19:     private static void GetANewPatron(string name)
  20:     {
  21:         ICantinaPatron patron = _cantina.GetPatron(name);
  22:         Console.WriteLine(patron.Name + " enters the cantina");
  23:         foreach (IStuff thing in patron.Basket)
  24:             Console.WriteLine(thing.DoSomething(patron));
  25:     }
  26:  
  27: }
  28:  
  29: public class Weasel : IFuzzyAnimal
  30: {
  31:     private string _name;
  32:     private string _playmate;
  33:  
  34:     public Weasel(string name)
  35:     {
  36:         _name = name;
  37:     }
  38:  
  39:     public string Name
  40:     {
  41:         get { return _name; }
  42:     }
  43:  
  44:     public string MakeNoise()
  45:     {
  46:         return
  47:             "Hi, " + _playmate + "!  My name is " + _name +
  48:             ", and I'm a weasel!  SSHHHHREEEIIIIKKKK!!!  HISSSSSSSS!!!!!";
  49:     }
  50:  
  51:     public string Play()
  52:     {
  53:         return _name + " rips " + _playmate + " a new orifice.";
  54:     }
  55:  
  56:     public string DoSomething(ICantinaPatron patron)
  57:     {
  58:         _playmate = patron.Name;
  59:         return MakeNoise() + "\r\n" + Play() + "\r\n";
  60:     }
  61: }
  62:  
  63: public class ConfusionOfWeasels : StuffStrategy
  64: {
  65:     public override void GetStuff(ICantinaPatron cantinaPatron)
  66:     {
  67:         cantinaPatron.Basket.Add(new Weasel("Lefty"));
  68:         cantinaPatron.Basket.Add(new Weasel("One Eye"));
  69:         cantinaPatron.Basket.Add(new Weasel("Sanchez"));
  70:         cantinaPatron.Basket.Add(new Weasel("Scar"));
  71:         cantinaPatron.Basket.Add(new Weasel("Ashes"));
  72:         cantinaPatron.Basket.Add(new Weasel("Blade"));
  73:         cantinaPatron.Basket.Add(new Weasel("Rainbow Dash"));
  74:     }
  75: }

What does poor Greedo get in his basket?  That's right: a really nasty confusion of weasels (that's the right term for a collection of weasels; I looked it up) named Lefty, One Eye, Sanchez, Scar, Ashes, Blade, and (oddly enough) Rainbow Dash!  Greedo flew halfway across the galaxy to bring Han back to Jabba, but instead here's what he gets for his troubles:

image

So what's the morale of this tale?  If you're a galactic bounty hunter and you ever find yourself in a desert planet cantina that's giving away baskets of fuzzy animals, be super careful, because what you think is gonna be a litter of kittens might just turn out to be a confusion of weasels.  And, oh yeah, the Strategy Pattern is a good way to achieve some nice decoupling in your design.  But seriously, don't forget about the weasel part.

Share this post :

No comments: