Java或c#中工厂设计模式中的反射

本文关键字:反射 设计模式 工厂 Java | 更新日期: 2023-09-27 18:06:06

我遇到了一个叫做反射的术语。这是工厂设计模式中常用的功能。我很难理解这个概念,因为我还在学习如何编程。如何在c#或Java的工厂设计模式中使用反射?谁能给我一个简单的例子,并告诉我你的代码,使用反射来实现工厂设计模式?

微软提供了这个反射的代码示例,但是我不知道如何在工厂设计模式中使用它。

 // Using GetType to obtain type information: 
  int i = 42;
  System.Type type = i.GetType();
  System.Console.WriteLine(type);
  The Output is: System.Int32

Java或c#中工厂设计模式中的反射

我永远不会使用反射来实现工厂设计模式,除非有特殊情况。下面的代码是实现工厂设计模式的糟糕方式。但是既然你想知道"如何"在工厂设计模式中使用反射,这里有一个例子:

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对象:

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版本

代码:

public class TestReflectionFactoryDesign {
    public static void main(String[] args) throws Exception {
        Person student = PersonFactory.getPersonWithFullQualifiedClassName("com.test.reflectionFactoryDesign.Student");
        student.say();
        Person teacher = PersonFactory.getPersonWithClass(Teacher.class);
        teacher.say();
        Person student2 = PersonFactory.getPersonWithName("student");
        student2.say();
    }
}
class Student implements Person {
    @Override
    public void say() {
        System.out.println("I am a student");
    }
}
class Teacher implements Person {
    @Override
    public void say() {
        System.out.println("I am a teacher");
    }
}
interface Person {
    void say();
}
class PersonFactory {
    // reflection, by full qualified class name
    public static Person getPersonWithFullQualifiedClassName(String personType) throws Exception {
        Class<?> personClass = Class.forName(personType);
        return getPersonWithClass(personClass);
    }
    // reflection, by passing class object
    public static Person getPersonWithClass(Class personClass) throws Exception {
        return (Person) personClass.newInstance();
    }
    // no reflection, the ordinary way
    public static Person getPersonWithName(String personType) {
        if (personType.equalsIgnoreCase("STUDENT")) {
            return new Student();
        } else if (personType.equalsIgnoreCase("TEACHER")) {
            return new Teacher();
        }
        return null;
    }
}
输出:

I am a student
I am a teacher
I am a student