There are tried-and-tested routes to replacing conditional statements that effectively map identities (e.g., if(x == “UK shipping”) ) to polymorphic implementations of what to do when an identity is determined (e.g. create a Shipping interface and then have a UKShipping class that knows what to do in that situation and pass that in to the method).
But sometimes I find, when the literal that represents the identity has to be preserved (for example, if it’s part of an API) that mapping identities to actions works better.
In these instances, I have found myself converting my conditionals to a map or dictionary instead. Each identity is mapped to a lambda expression that can be looked up and then executed.
The literals “rock”, “paper” and “scissors” have to be preserved because we have a web service that accepts those parameter values from remote players. (This is very similar to the Mars Rover kata in that respect, where R, L, F and B are inputs.)
First, I’d remove some obvious inner duplication in each outer IF statement.
Now let’s replace those 3 IF statements that map actions to “rock”, “paper” and “scissors” into an actual map.
If we take a look inside playHand(), we have an inner conditional.
This could also be replaced with a lambda map.
Note that I had to add a draws identity so that the mapping is complete. I’d also have to do this for any default case in a conditional (I suppose draws is the default case here, as nothing happens when there’s a draw – an empty lambda).