zoukankan      html  css  js  c++  java
  • 艾伟_转载:一个简单的 Generic Factory 类 狼人:

      简单的工厂类的一个使用场景是, 假设有一个基类 BaseClass, 和一系列的子类 A, B, C, 工厂类根据某个参数,例如字符串 “A”, “B”, “C” 创建出相应的子类。 举例如下:

    public class Factory
    {
        public static BaseClass Create(string name)
        {
            switch (name)
            {
                case "A": return new A();
                case "B": return new B();
                case "C": return new C();
                default: throw new ArgumentException("Wrong Name");
            }
        }
    }

      这里的一个问题是, 当子类增加或减少时, Factory 类 需要相应的改动。 有没有办法可以只是改动子类本身, 而不用修改Factory类呢, 当然有,这里我举一个简单的实现。

      基本思想是在每个子类上附加一个 Attribute, 定义如下:

    [AttributeUsage(AttributeTargets.Class)]
    public class FactoryKeyAttribute : Attribute
    {
        public object Key { get; set; }
    }

      假设我们有基类和子类实现如下

    public abstract class BaseClass {}
    [FactoryKey(Key = "Standard")]
    public class Standard : BaseClass {}
    [FactoryKey(Key = "Enterprise")]
    public class Enterprise : BaseClass {}
    [FactoryKey(Key = "Lite")]
    public class Lite : BaseClass {}

      假设这些类都在同一个 Assembly中 (对于不在同一个Assembly的,实现会稍微复杂些)工厂类需要预先加载 Key => Type 的Mapping, 然后根据Key创建不同的实例, 实现如下:

    public static class Factory<TKey, TBaseClass>
    {
        private static readonly IDictionary<TKey, Type> TypeDict = Init();
        private static IDictionary<TKey, Type> Init()
        {
            var dict = from type in Assembly.GetExecutingAssembly().GetTypes()
                       let key = (FactoryKeyAttribute)Attribute.GetCustomAttribute(type, typeof(FactoryK
    eyAttribute
    )) where key != null && type.IsSubclassOf(typeof(TBaseClass)) select new { Key = key, Value = type }; return dict.ToDictionary(kvp => (TKey)kvp.Key.Key, kvp => kvp.Value); } public static TBaseClass CreateInstance(TKey key) { Type type; if (TypeDict.TryGetValue(key, out type)) { return (TBaseClass)Activator.CreateInstance(type); } throw new ArgumentException("Incorrect Key!"); } }

      使用方法也很简单:

    BaseClass s = Factory<string, BaseClass>.CreateInstance("Standard");
    BaseClass l = Factory<string, BaseClass>.CreateInstance("Lite");
    BaseClass e = Factory<string, BaseClass>.CreateInstance("Enterprise");

      对于其他类型的Key,比如 Enum, 或其他类型的基类, 改变Factory 的类型参数即可。

  • 相关阅读:
    harbor 报错,注意harbor.yml文件格式。
    nginx中rewrite文件
    改善github网络连接
    代码层实现六种质量属性战术
    读漫谈架构有感
    “淘宝网”的六个质量属性的六个常见属性
    寒假学习进度16:tensorflow2.0 波士顿房价预测
    寒假学习进度15:tensorflow2.0 优化器
    寒假学习进度14:对mnist数据集实现逻辑回归
    寒假学习进度13:tensorflow2.0 mnist简介
  • 原文地址:https://www.cnblogs.com/waw/p/2157021.html
Copyright © 2011-2022 走看看