我遇到了一个叫做反射的术语。这是工厂设计模式中常用的功能。我很难理解这个概念,因为我仍在学习如何编程。如何在C#或Java的工厂设计模式中使用反射?谁能给我一个简单的例子,并向您展示使用反射实现工厂设计模式的代码?
Microsoft提供了此反射代码示例,但我不知道如何将其用于工厂设计模式。
// Using GetType to obtain type information: int i = 42; System.Type type = i.GetType(); System.Console.WriteLine(type); The Output is: System.Int32
除非有特殊情况,否则我绝不会使用反射来实现Factory设计模式。下面的代码是实现工厂设计模式的一种糟糕方法。但是由于您想知道“如何”将反射用于工厂设计模式,因此以下示例:
namespace NaiveFactory { public interface Shape { void Draw(); } public class Circle : Shape { public void Draw() { Console.WriteLine("Drawing Circle"); } } public class Rectangle : Shape { public void Draw() { Console.WriteLine("Drawing Rectangle"); } } public class ShapeFactory { public static Shape GetShape<T>() where T : Shape { return Activator.CreateInstance<T>(); } public static Shape GetShape(string shapeName) { var assembly = Assembly.GetExecutingAssembly(); var type = assembly.GetType(shapeName).FullName; return (Shape) Activator.CreateInstanceFrom(assembly.Location, type).Unwrap(); } } class Program { static void Main(string[] args) { var shape = ShapeFactory.GetShape<Circle>(); var shape2 = ShapeFactory.GetShape("NaiveFactory.Rectangle"); shape.Draw(); shape2.Draw(); Console.ReadKey(); } } }
编辑 根据@AlexeiLevenkov的建议,我在依赖注入中添加了一些内容,并Shape使用构造函数注入以及方法来实例化对象:
Shape
namespace NaiveFactory { public interface IBoard { void InternalDraw(string str); } public class ConsoleBoard : IBoard { public void InternalDraw(string str) { Console.WriteLine(str); } } public class DebugBoard : IBoard { public void InternalDraw(string str) { Debug.WriteLine(str); } } public interface Shape { IBoard Board { get; set; } void Draw(); void SetBoard(IBoard board); } public class Circle : Shape { public IBoard Board { get; set; } public Circle() { } public Circle(IBoard board) { Board = board; } public void Draw() { Board.InternalDraw("Drawing Circle"); } public void SetBoard(IBoard board) { Board = board; } } public class Rectangle : Shape { public IBoard Board { get; set; } public Rectangle() { } public Rectangle(IBoard board) { Board = board; } public void Draw() { Board.InternalDraw("Drawing Rectangle"); } public void SetBoard(IBoard board) { Board = board; } } public class ShapeFactory { private static Dictionary<Type, Type> _configurationData = new Dictionary<Type, Type>(); public static Shape GetShape<T>() where T : Shape { return Activator.CreateInstance<T>(); } public static void ConfigureContainer<T, U>() { _configurationData.Add(typeof(T), typeof(U)); } public static Shape GetShape_UsingConstructorInjection(string shapeName) { var assembly = Assembly.GetExecutingAssembly(); var type = assembly.GetType(shapeName); var constructor = type.GetConstructor(_configurationData.Keys.ToArray()); if (constructor != null) { var parameters = constructor.GetParameters(); return (from parameter in parameters where _configurationData.Keys.Contains(parameter.ParameterType) select Activator.CreateInstance(_configurationData[parameter.ParameterType]) into boardObj select (Shape) Activator.CreateInstance(type, boardObj)).FirstOrDefault(); } return null; } public static Shape GetShape_UsingSetBoardMethod(string shapeName) { var assembly = Assembly.GetExecutingAssembly(); var type = assembly.GetType(shapeName); var shapeObj = (Shape) Activator.CreateInstance(type); if (shapeObj != null) { shapeObj.SetBoard((IBoard) Activator.CreateInstance(_configurationData[typeof (IBoard)])); return shapeObj; } return null; } } class Program { static void Main(string[] args) { ShapeFactory.ConfigureContainer<IBoard, ConsoleBoard>(); var shape = ShapeFactory.GetShape_UsingSetBoardMethod("NaiveFactory.Circle"); var shape2 = ShapeFactory.GetShape_UsingConstructorInjection("NaiveFactory.Rectangle"); shape.Draw(); shape2.Draw(); Console.ReadKey(); } } }