繁体   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