Lets say we have a family of classes (cards, for the sake of it), and we need to instantiate them based on some identifier. A factory method would look like this:
public Card GetCard(int cardNumber) { switch(cardNumber) { case 13: return new King(); case 12: return new Queen(); case 11: return new Jack(); } //... }
What I want is to avoid this switch
. Why? Maybe I want to reuse this comparison in the feature.
What I came up with is something like this:
private Dictionary<int, Type> cardTypes = { {13, typeof(King)}, {12, typeof(Queen)}, {11, typeof(Jack)} }; public Card GetCard(int cardNumber) { var cardType = cardTypes[cardNumber]; var instance = Activator.CreateInstance(cardType); return (Card)instance; }
However, this solution uses reflection which is expensive, and is also problematic when you have more than one "identifier" (for example 1 and 14 both give Ace
- should I add 2 keys to the dictionary?).
What's the best practice in this scenario?
Instead of storing the type in the dictionary, you could store a Func<Card>
:
private Dictionary<int, Func<Card>> cardFactories = { { 13, () => new King() }, // etc } public Card GetCard(int cardNumber) { var factory = cardFactories[cardNumber]; return factory(); }
In the case of cards, I'd probably make them immutable to start with and just populate the dictionary with the cards themselves, but that's a different matter :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With