问题描述
我遇到了一个叫做反射的名词。这是工厂设计模式中常用的功能。我很难理解这个概念,因为我仍在学习如何编程。如何在C#或Java的工厂设计模式中使用反射?谁能给我一个简单的例子,并向我展示您使用反射实现工厂设计模式的代码?
I came across a term called reflection. It is a feature commonly used in factory design patterns. I had a hard time understanding the concept because I’m still learning how to program. How can reflection be used in factory design patterns in C# or Java? Can anyone give me a simple example, and show me your code that uses reflection to implement factory design patterns?
Microsoft提供了此反射示例代码,但我没有了解如何将其用于工厂设计模式。
Microsoft provides this code example of reflection, but i don't see how this can be used in factory design patterns.
// Using GetType to obtain type information:
int i = 42;
System.Type type = i.GetType();
System.Console.WriteLine(type);
The Output is: System.Int32
推荐答案
除非有特殊情况,否则我永远不会使用反射来实现Factory设计模式。下面的代码是实现工厂设计模式的一种糟糕方法。但是,由于您想知道如何将反射用于工厂设计模式,因此示例如下:
I would never use reflection to implement Factory design pattern, unless there was a special case. The below code is a terrible way to implement the factory design pattern. But since you wanted to know "How" to use reflection for factory design pattern here's the example:
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
对象实例化: / p>
EDITAs per suggestion from @AlexeiLevenkov, I have added something close to Dependency injection and instantiating the Shape
objects using Constructor Injection as well as with a method:
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();
}
}
}
这篇关于用Java或C#反映工厂设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!