利用反射实现工厂模式
需求
工厂类根据参数生成对应类的实例。
示例
RoomParts.cs
csharp
namespace ReflectionFactory
{
/// <summary>
/// 屋子产品的零件
/// </summary>
public enum RoomParts
{
Roof,
Window,
Pillar
}
}
ProductAttribute.cs
csharp
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
csharp
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
csharp
using System;
namespace ReflectionFactory
{
/// <summary>
/// 产品零件接口,
/// 需要添加所有实现该接口的列表
/// </summary>
[ProductList(new Type[] { typeof(Roof), typeof(Window), typeof(Pillar) })]
public interface IProduct
{
string GetName();
}
}
Roof.cs
csharp
namespace ReflectionFactory
{
/// <summary>
/// 屋顶类型
/// </summary>
[Product(RoomParts.Roof)]
public class Roof : IProduct
{
public string GetName()
{
return "屋顶";
}
}
}
Window.cs
csharp
namespace ReflectionFactory
{
/// <summary>
/// 窗户类型
/// </summary>
[Product(RoomParts.Window)]
public class Window : IProduct
{
public string GetName()
{
return "窗户";
}
}
}
Pillar.cs
csharp
namespace ReflectionFactory
{
/// <summary>
/// 柱子类型
/// </summary>
[Product(RoomParts.Pillar)]
public class Pillar : IProduct
{
public string GetName()
{
return "柱子";
}
}
}
IFactory.cs
csharp
namespace ReflectionFactory
{
public interface IFactory
{
IProduct Produce(RoomParts part);
}
}
Factory.cs
csharp
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
csharp
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
csharp
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();
}
}
}