簡體   English   中英

C# - 工廠模式如何使用反射?

[英]C# - Factory pattern using reflection or how?

我正在控制台 c# 中開發一款游戲,您可以讀取在文件中創建的地圖。 為此,我正在讀取一個文件並將其存儲到一個字符串中。 然后我單獨讀取每個字符並根據字符,我需要使用工廠模式創建一個 object。 如果不耦合代碼,我不知道該怎么做。

我有主要實體 Object。從 object 繼承不同的對象,如:盒子、牆、草、樹。 每一個都由文件中的一個字符表示並翻譯成游戲中的另一個字符,(B)ox = '■', (W)all = '↓', (G)rass = 'v', (T)ree ='↑'。 我這樣做的方法是在 Object 中放置一個屬性字符“模型”,僅使用吸氣劑,在每個 object 中,我用相應的 model 覆蓋吸氣劑。

現在,當我讀取之前提到的文件 map 時,我需要根據讀取的字符告訴工廠要構建哪個 object。 我不想做一個大開關(字符),因為它會耦合,因為對於每個我想添加的 object,我都必須在開關中添加一個新的案例。 有更好的方法嗎?

class 框示例:

public class Box : Object
{
    public override char Model { get { return '■'; } }

    public Box()
    {
        this.Name = "box";
        this.MapCharacter = 'B';
        this.Colors = new List<ConsoleColor>() { ConsoleColor.DarkYellow };
        this.Destructible = true;
        this.Passable = false;
        this.SeeThrough = false;
        this.Health = 200;
    }

    public override void OnDestroy()
    {
    }
}

工廠示例代碼:

public class ObjectFactory : IObjectFactory
{
    public Object GetObject(char mapCharacter)
    {
        switch (mapCharacter)
        {
            case 'B':
                return new Box();
            case 'T':
                return new Tree();
            case 'W':
                return new Wall();
            case 'G':
                return new Grass();
            default:
                return null;
        }
    }
}

我的想法是使用反射獲取從 Object 繼承的每個 class 的 Model 並以某種方式返回 class,但這似乎是糟糕的代碼

使用反射有利有弊(在一般情況下我個人不會 go 這種方式)但是使用當前代碼你可以稍微改進它並通過“轉換” switch到字典來減少樣板:

public class ObjectFactory 
{
    private static readonly Dictionary<char, Func<MyObject>> _objectFactory = new Dictionary<char, Func<MyObject>>()
    {
        { 'B', () => new Box() },
        // ...
    };

    public Object GetObject(char mapCharacter)
    {
        if(_objectFactory.TryGetValue(mapCharacter, out var factory))
        {
            return factory();
        }

        return null;
    }
}

如果您決定每次都向字典添加項目太多了——我建議查看源代碼生成器,如果這種方法太多了——不要忘記“緩存”反射。

值得一看Activator.CreateInstance方法。

如果 map 的全名是 class,則可以創建這樣的實例:

public class InstanceHelper
{
    public static object Get(string fullyQualifiedName)
    {
        Type t = Type.GetType(fullyQualifiedName);
        return Activator.CreateInstance(t);
    }
}

所以上面的代碼可以這樣調用:

Box box = InstanceHelper.Get("Box") as Box;

您可以使用此代碼示例 有一個名為EnhancedShapeFactory的 class,它使用反射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM