如何避免在子类的工厂方法的switch-case [英] How to avoid switch-case in a factory method of child classes
问题描述
假设我们有一个类家族(卡,它的缘故),我们需要根据一些标识符来实例化它们。
工厂方法是这样的:
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.
我来得到的是这样的:
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;
}
然而,这种解决方案使用反射这是昂贵的,并且也有问题时有一个以上的标识符(例如1和14都给予王牌
? - 我要补充2键到词典中)。
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?
推荐答案
而不是存储的键入在字典中,你可以存储一个 Func键<卡>
:
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 :)
这篇关于如何避免在子类的工厂方法的switch-case的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!