Как избежать коммутационного случая в методе factory дочерних классов
Допустим, у нас есть семейство классов (карт, для этого), и нам нужно создать их на основе некоторого идентификатора.
Метод factory будет выглядеть следующим образом:
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 слова в словарь?).
Какая наилучшая практика в этом сценарии?
Ответы
Ответ 1
Вместо сохранения типа в словаре вы можете сохранить Func<Card>
:
private Dictionary<int, Func<Card>> cardFactories =
{
{ 13, () => new King() },
// etc
}
public Card GetCard(int cardNumber)
{
var factory = cardFactories[cardNumber];
return factory();
}
В случае карт, я бы, вероятно, сделать их неизменны, чтобы начать с и просто заполнить словарь с самих карт, но это другое дело:)