Advertisements
Posted by: jsonmez | February 25, 2010

Super Combo: Map + Function Pointer

Anyone who has coded with me, if asked to describe me in three words would say…

Function-Pointer, Enumeration, Map


When I get to combine 2 or more of these things together, I am usually pretty excited!  Map + Function Pointer to me is like a kick in the face to code duplication!

Why is this little combo so awesome?

Let me give you a little code example:

public void HandleData(DataPackage package)
{
    string packageType = package.GetType();
    switch(packageType)
    {
        case "RoundHouseKick":
            Player.RoundHouseKick(package.destination);
            break;

        case "FaceSlap":
            Player.FaceSlap(package.destination);
            break;

        case "EvilEye":
            Player.Taunt(package.destination);
            break;

        case "Bite":
            Player.Bite(package.destination);
            break;

        case "FireBall":
            Player.Fireball(package.destination);
            break;
    }
}

Rewriting this as a super-awesome-hard-to-contain-myself map of function pointers you get:

private Dictionary<string, Func<Destination>> moveMap = new Dictionary<string, Func<Destination>>()
{
   { "RoundHouseKick", Player.RoundHouseKick },
   { "FaceSlap", Player.FaceSlap },
   { "EvilEye", Player.Taunt },
   { "Bite", Player.Bite },
   { "FireBall", Player.FireBall },
};

public void HandleData2(DataPackage package)
{
   string packageType = package.GetType();
   moveMap[packageType](package.destination);
}

Now if we forgo the use of strings, but use an enumeration from the get go…  We achieve the most-super-awesome-ultimate-combo MAP OF ENUMERATIONS TO FUNCTION POINTERS!!!

public enum Moves
{
    RoundHouseKick,
    FaceSlap,
    EvilEye,
    Bite,
    FireBall
}

private Dictionary<Moves, Func<Destination>> moveMap = new Dictionary<Moves, Func<Destination>>()
{
    { Moves.RoundHouseKick, Player.RoundHouseKick },
    { Moves.FaceSlap, Player.FaceSlap },
    { Moves.EvilEye, Player.Taunt },
    { Moves.Bite, Player.Bite },
    { Moves.FireBall, Player.FireBall },
};

public void HandleData2(DataPackage package)
{
    Moves moveType = package.GetType();
    moveMap[moveType](package.destination);
}

Why is this so super awesome?

It isn’t as apparent in a little code snippet, but imagine an application where you have many sections of code that deal with this logic in the same way.  Often you encounter a third-party API that has methods or properties that are named after the type of data they work on or retrieve instead of having a parameter passed in.  In situations like these, it is very useful to map the mapping between data and logic into one location.

I also don’t like switch statements very much.  They can be confusing with the break statements in there, and end up being duplicated all over of the code base.  Anytime you see a switch statement in code, it is a possible candidate for the super-fantastic-mega-awesome-30-hit-combo of Map + Function pointer.

Advertisements

Responses

  1. […] Super Combo: Map + Function Pointer – John Sonmez shares one of his favourite techniques for improving code, combining a map with function pointers and enumerations to help replace a string based switch statement – a nice coding technique, with a good clear example to help explain […]

  2. Another advantage is that you can use this with any key that is comparable, including Type etc.

    While switch is more limited 🙂

  3. In the final bit of code, in HandleData2 you reference packageType which is no longer declared in the enumeration scenario. Shouldn’t that be moveMap[moveType]?

    • You are correct. I fixed it thanks. 🙂

  4. The other benefit to this is that you could potentially persist the map somewhere (database, config file) and change behaviour without changing code!

  5. […] Combine them with maps and function pointers for the ultimate combo! […]

  6. […] also wanted to note here that I didn’t use enumerations.  In real code you should.  I avoided them here to prevent adding one more layer of abstraction […]

  7. This isn’t csharp code is it?

    • It’s kind of a javasharp code. I think you get the idea though.

      • Righto!

        Thanks

  8. […] Super Combo: Map + Function Pointer […]

  9. am i missing something here – shouldn’t your Funcs be Actions?

    • Yes, you are right. I was writing code fast at night without an IDE 😛

      • brave man 🙂

  10. Wow, really very awesome! =) (Y)

  11. I don’t understand the sentence:
    moveMap[moveType](package.destination);
    We get a func by ‘moveType’ and invoke it, right? So why it has 1 input parameter (package destination), Func – is a method which takes no parameters and returns one, correct? Could we write so in this case:
    moveMap[moveType].Invoke()?

    • It does take a parameter


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: