如何避免子类的工厂方法中的switch-case

yel*_*ood 22 c# design-patterns

假设我们有一系列类(卡片,为了它),我们需要根据一些标识符实例化它们.工厂方法如下所示:

public Card GetCard(int cardNumber) 
{
   switch(cardNumber) 
   {
     case 13: return new King();
     case 12: return new Queen();
     case 11: return new Jack();          
   }

   //...
}
Run Code Online (Sandbox Code Playgroud)

我想要的是避免这种情况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;
 }
Run Code Online (Sandbox Code Playgroud)

但是,此解决方案使用昂贵的反射,并且当您有多个"标识符"时也会出现问题(例如,1和14都给出Ace- 我应该在字典中添加2个键吗?).

这种情况下的最佳做法是什么?

Jon*_*eet 46

您可以存储以下内容,而不是将类型存储在字典中Func<Card>:

private Dictionary<int, Func<Card>> cardFactories = 
{
    { 13, () => new King() },
    // etc
}

public Card GetCard(int cardNumber) 
{        
    var factory = cardFactories[cardNumber];
    return factory();
}
Run Code Online (Sandbox Code Playgroud)

在卡片的情况下,我可能会让它们一开始就不变,只是用卡片本身填充字典,但这是另一回事:)

  • @Caspar:是的,你当然可以使用常量.然而,这不是问题的重点,这正是我试图解决的问题...... (3认同)