zoukankan      html  css  js  c++  java
  • 利用反射实现工厂模式

    需求:工厂类根据参数生成对应类的实例。

    示例:

    RoomParts.cs

    namespace ReflectionFactory
    {
        /// <summary>
        /// 屋子产品的零件
        /// </summary>
        public enum RoomParts
        {
            Roof,
            Window,
            Pillar
        }
    }

    ProductAttribute.cs

    using System;
    
    namespace ReflectionFactory
    {
        /// <summary>
        /// 这个特性用来附加在产品类型之上,
        /// 来标注该类型代表哪个产品,方便反射使用
        /// </summary>
        public class ProductAttribute : Attribute
        {
            /// <summary>
            /// 标注零件的成员
            /// </summary>
            private RoomParts _myRoomPart;
            public ProductAttribute(RoomParts part)
            {
                _myRoomPart = part;
            }
            public RoomParts RoomPart
            {
                get
                {
                    return _myRoomPart;
                }
            }
        }
    }

    ProductListAttribute.cs

    using System;
    
    namespace ReflectionFactory
    {
        /// <summary>
        /// 这个特性用来附加在产品接口之上
        /// 用来标注一共实现了多少产品零件,方便反射使用
        /// </summary>
        public class ProductListAttribute : Attribute
        {
            /// <summary>
            /// 产品类型集合
            /// </summary>
            private Type[] _myList;
            public ProductListAttribute(Type[] products)
            {
                _myList = products;
            }
            public Type[] ProductList
            {
                get
                {
                    return _myList;
                }
            }
        }
    }

    IProduct.cs

    using System;
    
    namespace ReflectionFactory
    {
        /// <summary>
        /// 产品零件接口,
        /// 需要添加所有实现该接口的列表
        /// </summary>
        [ProductList(new Type[] { typeof(Roof), typeof(Window), typeof(Pillar) })]
        public interface IProduct
        {
            string GetName();
        }
    }

    Roof.cs

    namespace ReflectionFactory
    {
        /// <summary>
        /// 屋顶类型
        /// </summary>
        [Product(RoomParts.Roof)]
        public class Roof : IProduct
        {
            public string GetName()
            {
                return "屋顶";
            }
        }
    }

    Window.cs

    namespace ReflectionFactory
    {
        /// <summary>
        /// 窗户类型
        /// </summary>
        [Product(RoomParts.Window)]
        public class Window : IProduct
        {
            public string GetName()
            {
                return "窗户";
            }
        }
    }

    Pillar.cs

    namespace ReflectionFactory
    {
        /// <summary>
        /// 柱子类型
        /// </summary>
        [Product(RoomParts.Pillar)]
        public class Pillar : IProduct
        {
            public string GetName()
            {
                return "柱子";
            }
        }
    }

    IFactory.cs

    namespace ReflectionFactory
    {
        public interface IFactory
        {
            IProduct Produce(RoomParts part);
        }
    }

    Factory.cs

    using System;
    using System.Reflection;
    
    namespace ReflectionFactory
    {
        /// <summary>
        /// 工厂类型
        /// </summary>
        public class Factory : IFactory
        {
            public IProduct Produce(RoomParts part)
            {
                // 通过反射,从IProduct接口获得属性
                // 从而获得所有的产品零件列表
                ProductListAttribute attr = Attribute.GetCustomAttribute(typeof(IProduct), 
                    typeof(ProductListAttribute)) as ProductListAttribute;
    
                // 遍历所有的实现产品零件类型
                foreach (Type type in attr.ProductList)
                {
                    // 利用发射查找其属性
                    ProductAttribute pa = Attribute.GetCustomAttribute(type, 
                        typeof(ProductAttribute)) as ProductAttribute;
                    // 确定是否是需要的零件
                    if (pa.RoomPart == part)
                    {
                        // 利用反射创建产品零件类型
                        Object product = Assembly.GetExecutingAssembly().CreateInstance(type.FullName);
                        return product as IProduct;
                    }
                }
                
                return null;
            }
        }
    }

    FactoryManager.cs

    using System;
    
    namespace ReflectionFactory
    {
        /// <summary>
        /// 工厂管理类型
        /// </summary>
        public class FactoryManager
        {
            public static IProduct GetProduct(RoomParts part)
            {
                // 一共只有一个工厂,不再需要根据产品类型而挑选工厂
                Factory factory = new Factory();
                IProduct product = factory.Produce(part);
                Console.WriteLine("生产了一个产品:" + product.GetName());
                return product;
            }
        }
    }

    Program.cs

    using System;
    
    namespace ReflectionFactory
    {
        class Program
        {
            static void Main(string[] args)
            {
                // output : 生产了一个产品:柱子
                IProduct pillar = FactoryManager.GetProduct(RoomParts.Pillar);
                // output : 生产了一个产品:屋顶
                IProduct roof = FactoryManager.GetProduct(RoomParts.Roof);
                // output : 生产了一个产品:窗户
                IProduct window = FactoryManager.GetProduct(RoomParts.Window);
                Console.Read();
            }
        }
    }
  • 相关阅读:
    Python基础学习四 文件操作(二)
    Python基础学习三 文件操作(一)
    Python基础学习三 字符串
    Python基础学习三 字典、元组
    Python基础学习三 list-增删改查、切片、循环、排序
    python基础4文件操作
    Python基础3切片,字符串的方法,for 循环
    python2和Python3的区别(长期更新)
    Python基础1
    python 中的enumerate()函数的用法
  • 原文地址:https://www.cnblogs.com/Ryukaka/p/5161876.html
Copyright © 2011-2022 走看看