可以说我们有一个类家族(为方便起见,使用卡),我们需要根据一些标识符实例化它们。
工厂方法如下所示:
public Card GetCard(int cardNumber)
{
switch(cardNumber)
{
case 13: return new King();
case 12: return new Queen();
case 11: return new Jack();
}
//...
}
我要避免的是
switch
。为什么?也许我想在功能中重用此比较。我想到的是这样的:
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都给出
Ace
-我是否应该在字典中添加2个键?),反射也很成问题。在这种情况下,最佳做法是什么?
最佳答案
除了将类型存储在字典中之外,还可以存储Func<Card>
:
private Dictionary<int, Func<Card>> cardFactories =
{
{ 13, () => new King() },
// etc
}
public Card GetCard(int cardNumber)
{
var factory = cardFactories[cardNumber];
return factory();
}
在卡片的情况下,我可能会让它们从一开始就不可变,而只是用卡片本身来填充字典,但这是另一回事:)