Today I Learned - Rocky Kev

TIL Redefining the environment, not the function itself

POSTED ON:

TAGS:

I think we all can agree that something smells with this code.

public void Draw(CardDeck cardDeck, string[] cardTypes) {

if(cardDeck.amountOfCards > 0) {
string cardType = cardTypes[new Random().Next(0, cardTypes.Length+1)];

switch (cardType) {
case "MonsterCard":
PutCardToHand(cardType);
break;
case "MagicCard":
PutCardToHand(cardType);
break;
case "TrapCard":
PutCardToHand(cardType);
break;
case "LandCard":
PutCardToHand(cardType);
break;
}

cardDeck.amountOfCards--;
}
}

private void PutCardToHand(string cardType) {
Console.WriteLine("Draw a {0}.", cardType);
}

It's written in C#. It's not at all difficult for a JS dev to interpret (or even rewrite in JS). (If it is, feel free to Twitter me at @rockykev and I'll do it!)

But let's point out the obvious issue:
That switch statement.

In this blog post

The author refactors that whole block. But there's something they write that really made sense to me.

"[What the solutions have in common are that] They are expandable by just redefining the environment, not the function itself."

The main issues we were addressing is that the Draw function was tied really heavily into the card types. If you wanted to add a new set of cards, say a ItemCard, heroCard and fusionCard, you would have to go into that function. Smells funny, right?

In his solutions, they migrates the switch statement out by:

  1. Turning the switch into an array

  2. Creating a separate helper function or chaining it.

  3. Return the results into the data.

In other words, removing the card types OUT of the Draw function, and into it's own space. Redefine the environment. Separate your concerns. Make each function do one specific thing.

Fun.


Related TILs

Tagged:

TIL Indirection and Swallowing the error

Op shared a tryCatch util that is problematic.

TIL reusing variables

Do not reuse variables. Do not double define variables that represent the same thing.

TIL about semaphores

A semaphore limits access to a resource to some number of consumers. Any new requests for the resource will get stalled until later, eventually to be handled.