如何避免在子类的工厂方法的switch-case [英] How to avoid switch-case in a factory method of child classes

查看:140
本文介绍了如何避免在子类的工厂方法的switch-case的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个类家族(卡,它的缘故),我们需要根据一些标识符来实例化它们。
工厂方法是这样的:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆